1 /* 2 Copyright (c) 2008 KJK::Hyperion 3 4 Permission is hereby granted, free of charge, to any person obtaining a 5 copy of this software and associated documentation files (the "Software"), 6 to deal in the Software without restriction, including without limitation 7 the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 and/or sell copies of the Software, and to permit persons to whom the 9 Software is furnished to do so, subject to the following conditions: 10 11 The above copyright notice and this permission notice shall be included in 12 all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 DEALINGS IN THE SOFTWARE. 21 */ 22 23 #include <pseh/pseh2.h> 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 #include <wine/test.h> 30 #undef subtest 31 32 extern void no_op(void); 33 extern int return_arg(int); 34 35 extern int return_zero(void); 36 extern int return_positive(void); 37 extern int return_negative(void); 38 extern int return_one(void); 39 extern int return_minusone(void); 40 41 extern int return_zero_2(void *); 42 extern int return_positive_2(void *); 43 extern int return_negative_2(void *); 44 extern int return_one_2(void *); 45 extern int return_minusone_2(void *); 46 47 extern int return_zero_3(int); 48 extern int return_positive_3(int); 49 extern int return_negative_3(int); 50 extern int return_one_3(int); 51 extern int return_minusone_3(int); 52 53 extern int return_zero_4(void *, int); 54 extern int return_positive_4(void *, int); 55 extern int return_negative_4(void *, int); 56 extern int return_one_4(void *, int); 57 extern int return_minusone_4(void *, int); 58 59 extern void set_positive(int *); 60 61 //static int call_test(int (*)(void)); 62 63 #ifdef __cplusplus 64 } // extern "C" 65 #endif 66 67 #define DEFINE_TEST(NAME_) static int NAME_(void) 68 69 /* Empty statements *///{{{ 70 DEFINE_TEST(test_empty_1) 71 { 72 _SEH2_TRY { } _SEH2_EXCEPT(0) { } _SEH2_END; 73 return 1; 74 } 75 76 DEFINE_TEST(test_empty_2) 77 { 78 _SEH2_TRY { } _SEH2_EXCEPT(-1) { } _SEH2_END; 79 return 1; 80 } 81 82 DEFINE_TEST(test_empty_3) 83 { 84 _SEH2_TRY { } _SEH2_EXCEPT(1) { } _SEH2_END; 85 return 1; 86 } 87 88 DEFINE_TEST(test_empty_4) 89 { 90 _SEH2_TRY { } _SEH2_FINALLY { } _SEH2_END; 91 return 1; 92 } 93 94 DEFINE_TEST(test_empty_5) 95 { 96 _SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(0) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END; 97 return 1; 98 } 99 100 DEFINE_TEST(test_empty_6) 101 { 102 _SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(-1) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END; 103 return 1; 104 } 105 106 DEFINE_TEST(test_empty_7) 107 { 108 _SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(1) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END; 109 return 1; 110 } 111 112 DEFINE_TEST(test_empty_8) 113 { 114 _SEH2_TRY { _SEH2_TRY { } _SEH2_FINALLY { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END; 115 return 1; 116 } 117 //}}} 118 119 /* Static exception filters *///{{{ 120 DEFINE_TEST(test_execute_handler_1) 121 { 122 static int ret; 123 124 ret = return_zero(); 125 126 _SEH2_TRY 127 { 128 RaiseException(0xE00DEAD0, 0, 0, NULL); 129 ret = return_zero(); 130 } 131 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 132 { 133 ret = return_positive(); 134 } 135 _SEH2_END; 136 137 return ret == return_positive(); 138 } 139 140 DEFINE_TEST(test_continue_execution_1) 141 { 142 static int ret; 143 144 ret = return_zero(); 145 146 _SEH2_TRY 147 { 148 RaiseException(0xE00DEAD0, 0, 0, NULL); 149 ret = return_positive(); 150 } 151 _SEH2_EXCEPT(EXCEPTION_CONTINUE_EXECUTION) 152 { 153 ret = return_zero(); 154 } 155 _SEH2_END; 156 157 return ret == return_positive(); 158 } 159 160 DEFINE_TEST(test_continue_search_1) 161 { 162 static int ret; 163 164 ret = return_zero(); 165 166 _SEH2_TRY 167 { 168 _SEH2_TRY 169 { 170 RaiseException(0xE00DEAD0, 0, 0, NULL); 171 ret = return_zero(); 172 } 173 _SEH2_EXCEPT(EXCEPTION_CONTINUE_SEARCH) 174 { 175 ret = return_zero(); 176 } 177 _SEH2_END; 178 } 179 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 180 { 181 ret = return_positive(); 182 } 183 _SEH2_END; 184 185 return ret == return_positive(); 186 } 187 188 DEFINE_TEST(test_execute_handler_2) 189 { 190 static int ret; 191 192 ret = return_zero(); 193 194 _SEH2_TRY 195 { 196 RaiseException(0xE00DEAD0, 0, 0, NULL); 197 ret = return_zero(); 198 } 199 _SEH2_EXCEPT(12345) 200 { 201 ret = return_positive(); 202 } 203 _SEH2_END; 204 205 return ret == return_positive(); 206 } 207 208 DEFINE_TEST(test_continue_execution_2) 209 { 210 static int ret; 211 212 ret = return_zero(); 213 214 _SEH2_TRY 215 { 216 RaiseException(0xE00DEAD0, 0, 0, NULL); 217 ret = return_positive(); 218 } 219 _SEH2_EXCEPT(-12345) 220 { 221 ret = return_zero(); 222 } 223 _SEH2_END; 224 225 return ret == return_positive(); 226 } 227 //}}} 228 229 /* Dynamic exception filters *///{{{ 230 DEFINE_TEST(test_execute_handler_3) 231 { 232 static int ret; 233 234 ret = return_zero(); 235 236 _SEH2_TRY 237 { 238 RaiseException(0xE00DEAD0, 0, 0, NULL); 239 ret = return_zero(); 240 } 241 _SEH2_EXCEPT(return_one()) 242 { 243 ret = return_positive(); 244 } 245 _SEH2_END; 246 247 return ret == return_positive(); 248 } 249 250 DEFINE_TEST(test_continue_execution_3) 251 { 252 static int ret; 253 254 ret = return_zero(); 255 256 _SEH2_TRY 257 { 258 RaiseException(0xE00DEAD0, 0, 0, NULL); 259 ret = return_positive(); 260 } 261 _SEH2_EXCEPT(return_minusone()) 262 { 263 ret = return_zero(); 264 } 265 _SEH2_END; 266 267 return ret == return_positive(); 268 } 269 270 DEFINE_TEST(test_continue_search_2) 271 { 272 static int ret; 273 274 ret = return_zero(); 275 276 _SEH2_TRY 277 { 278 _SEH2_TRY 279 { 280 RaiseException(0xE00DEAD0, 0, 0, NULL); 281 ret = return_zero(); 282 } 283 _SEH2_EXCEPT(return_zero()) 284 { 285 ret = return_zero(); 286 } 287 _SEH2_END; 288 } 289 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 290 { 291 ret = return_positive(); 292 } 293 _SEH2_END; 294 295 return ret == return_positive(); 296 } 297 298 DEFINE_TEST(test_execute_handler_4) 299 { 300 static int ret; 301 302 ret = return_zero(); 303 304 _SEH2_TRY 305 { 306 RaiseException(0xE00DEAD0, 0, 0, NULL); 307 ret = return_zero(); 308 } 309 _SEH2_EXCEPT(return_positive()) 310 { 311 ret = return_positive(); 312 } 313 _SEH2_END; 314 315 return ret == return_positive(); 316 } 317 318 DEFINE_TEST(test_continue_execution_4) 319 { 320 static int ret; 321 322 ret = return_zero(); 323 324 _SEH2_TRY 325 { 326 RaiseException(0xE00DEAD0, 0, 0, NULL); 327 ret = return_positive(); 328 } 329 _SEH2_EXCEPT(return_negative()) 330 { 331 ret = return_zero(); 332 } 333 _SEH2_END; 334 335 return ret == return_positive(); 336 } 337 //}}} 338 339 /* Dynamic exception filters, using _SEH2_GetExceptionInformation() *///{{{ 340 DEFINE_TEST(test_execute_handler_5) 341 { 342 static int ret; 343 344 ret = return_zero(); 345 346 _SEH2_TRY 347 { 348 RaiseException(0xE00DEAD0, 0, 0, NULL); 349 ret = return_zero(); 350 } 351 _SEH2_EXCEPT(return_one_2(_SEH2_GetExceptionInformation())) 352 { 353 ret = return_positive(); 354 } 355 _SEH2_END; 356 357 return ret == return_positive(); 358 } 359 360 DEFINE_TEST(test_continue_execution_5) 361 { 362 static int ret; 363 364 ret = return_zero(); 365 366 _SEH2_TRY 367 { 368 RaiseException(0xE00DEAD0, 0, 0, NULL); 369 ret = return_positive(); 370 } 371 _SEH2_EXCEPT(return_minusone_2(_SEH2_GetExceptionInformation())) 372 { 373 ret = return_zero(); 374 } 375 _SEH2_END; 376 377 return ret == return_positive(); 378 } 379 380 DEFINE_TEST(test_continue_search_3) 381 { 382 static int ret; 383 384 ret = return_positive(); 385 386 _SEH2_TRY 387 { 388 _SEH2_TRY 389 { 390 RaiseException(0xE00DEAD0, 0, 0, NULL); 391 ret = return_zero(); 392 } 393 _SEH2_EXCEPT(return_zero_2(_SEH2_GetExceptionInformation())) 394 { 395 ret = return_zero(); 396 } 397 _SEH2_END; 398 } 399 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 400 { 401 ret = return_arg(ret); 402 } 403 _SEH2_END; 404 405 return ret == return_positive(); 406 } 407 408 DEFINE_TEST(test_execute_handler_6) 409 { 410 static int ret; 411 412 ret = return_zero(); 413 414 _SEH2_TRY 415 { 416 RaiseException(0xE00DEAD0, 0, 0, NULL); 417 ret = return_zero(); 418 } 419 _SEH2_EXCEPT(return_positive_2(_SEH2_GetExceptionInformation())) 420 { 421 ret = return_positive(); 422 } 423 _SEH2_END; 424 425 return ret == return_positive(); 426 } 427 428 DEFINE_TEST(test_continue_execution_6) 429 { 430 static int ret; 431 432 ret = return_zero(); 433 434 _SEH2_TRY 435 { 436 RaiseException(0xE00DEAD0, 0, 0, NULL); 437 ret = return_positive(); 438 } 439 _SEH2_EXCEPT(return_negative_2(_SEH2_GetExceptionInformation())) 440 { 441 ret = return_zero(); 442 } 443 _SEH2_END; 444 445 return ret == return_positive(); 446 } 447 //}}} 448 449 /* Dynamic exception filters, using _SEH2_GetExceptionCode() *///{{{ 450 DEFINE_TEST(test_execute_handler_7) 451 { 452 static int ret; 453 454 ret = return_zero(); 455 456 _SEH2_TRY 457 { 458 RaiseException(0xE00DEAD0, 0, 0, NULL); 459 ret = return_zero(); 460 } 461 _SEH2_EXCEPT(return_one_3(_SEH2_GetExceptionCode())) 462 { 463 ret = return_positive(); 464 } 465 _SEH2_END; 466 467 return ret == return_positive(); 468 } 469 470 DEFINE_TEST(test_continue_execution_7) 471 { 472 static int ret; 473 474 ret = return_zero(); 475 476 _SEH2_TRY 477 { 478 RaiseException(0xE00DEAD0, 0, 0, NULL); 479 ret = return_positive(); 480 } 481 _SEH2_EXCEPT(return_minusone_3(_SEH2_GetExceptionCode())) 482 { 483 ret = return_zero(); 484 } 485 _SEH2_END; 486 487 return ret == return_positive(); 488 } 489 490 DEFINE_TEST(test_continue_search_4) 491 { 492 static int ret; 493 494 ret = return_zero(); 495 496 _SEH2_TRY 497 { 498 _SEH2_TRY 499 { 500 RaiseException(0xE00DEAD0, 0, 0, NULL); 501 ret = return_zero(); 502 } 503 _SEH2_EXCEPT(return_zero_3(_SEH2_GetExceptionCode())) 504 { 505 ret = return_zero(); 506 } 507 _SEH2_END; 508 } 509 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 510 { 511 ret = return_positive(); 512 } 513 _SEH2_END; 514 515 return ret == return_positive(); 516 } 517 518 DEFINE_TEST(test_execute_handler_8) 519 { 520 static int ret; 521 522 ret = return_zero(); 523 524 _SEH2_TRY 525 { 526 RaiseException(0xE00DEAD0, 0, 0, NULL); 527 ret = return_zero(); 528 } 529 _SEH2_EXCEPT(return_positive_3(_SEH2_GetExceptionCode())) 530 { 531 ret = return_positive(); 532 } 533 _SEH2_END; 534 535 return ret == return_positive(); 536 } 537 538 DEFINE_TEST(test_continue_execution_8) 539 { 540 static int ret; 541 542 ret = return_zero(); 543 544 _SEH2_TRY 545 { 546 RaiseException(0xE00DEAD0, 0, 0, NULL); 547 ret = return_positive(); 548 } 549 _SEH2_EXCEPT(return_negative_3(_SEH2_GetExceptionCode())) 550 { 551 ret = return_zero(); 552 } 553 _SEH2_END; 554 555 return ret == return_positive(); 556 } 557 //}}} 558 559 /* Dynamic exception filters, using _SEH2_GetExceptionInformation() and _SEH2_GetExceptionCode() *///{{{ 560 DEFINE_TEST(test_execute_handler_9) 561 { 562 static int ret; 563 564 ret = return_zero(); 565 566 _SEH2_TRY 567 { 568 RaiseException(0xE00DEAD0, 0, 0, NULL); 569 ret = return_zero(); 570 } 571 _SEH2_EXCEPT(return_one_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode())) 572 { 573 ret = return_positive(); 574 } 575 _SEH2_END; 576 577 return ret == return_positive(); 578 } 579 580 DEFINE_TEST(test_continue_execution_9) 581 { 582 static int ret; 583 584 ret = return_zero(); 585 586 _SEH2_TRY 587 { 588 RaiseException(0xE00DEAD0, 0, 0, NULL); 589 ret = return_positive(); 590 } 591 _SEH2_EXCEPT(return_minusone_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode())) 592 { 593 ret = return_zero(); 594 } 595 _SEH2_END; 596 597 return ret == return_positive(); 598 } 599 600 DEFINE_TEST(test_continue_search_5) 601 { 602 static int ret; 603 604 ret = return_zero(); 605 606 _SEH2_TRY 607 { 608 _SEH2_TRY 609 { 610 RaiseException(0xE00DEAD0, 0, 0, NULL); 611 ret = return_zero(); 612 } 613 _SEH2_EXCEPT(return_zero_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode())) 614 { 615 ret = return_zero(); 616 } 617 _SEH2_END; 618 } 619 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 620 { 621 ret = return_positive(); 622 } 623 _SEH2_END; 624 625 return ret == return_positive(); 626 } 627 628 DEFINE_TEST(test_execute_handler_10) 629 { 630 static int ret; 631 632 ret = return_zero(); 633 634 _SEH2_TRY 635 { 636 RaiseException(0xE00DEAD0, 0, 0, NULL); 637 ret = return_zero(); 638 } 639 _SEH2_EXCEPT(return_positive_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode())) 640 { 641 ret = return_positive(); 642 } 643 _SEH2_END; 644 645 return ret == return_positive(); 646 } 647 648 DEFINE_TEST(test_continue_execution_10) 649 { 650 static int ret; 651 652 ret = return_zero(); 653 654 _SEH2_TRY 655 { 656 RaiseException(0xE00DEAD0, 0, 0, NULL); 657 ret = return_positive(); 658 } 659 _SEH2_EXCEPT(return_negative_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode())) 660 { 661 ret = return_zero(); 662 } 663 _SEH2_END; 664 665 return ret == return_positive(); 666 } 667 //}}} 668 669 /* Constant exception filters with side effects *///{{{ 670 DEFINE_TEST(test_execute_handler_11) 671 { 672 static int ret; 673 674 ret = return_zero(); 675 676 _SEH2_TRY 677 { 678 RaiseException(0xE00DEAD0, 0, 0, NULL); 679 ret = return_zero(); 680 } 681 _SEH2_EXCEPT(set_positive(&ret), EXCEPTION_EXECUTE_HANDLER) 682 { 683 ret = ret ? return_positive() : return_zero(); 684 } 685 _SEH2_END; 686 687 return ret == return_positive(); 688 } 689 690 DEFINE_TEST(test_continue_execution_11) 691 { 692 static int ret; 693 694 ret = return_zero(); 695 696 _SEH2_TRY 697 { 698 RaiseException(0xE00DEAD0, 0, 0, NULL); 699 ret = ret ? return_positive() : return_zero(); 700 } 701 _SEH2_EXCEPT(set_positive(&ret), EXCEPTION_CONTINUE_EXECUTION) 702 { 703 ret = return_zero(); 704 } 705 _SEH2_END; 706 707 return ret == return_positive(); 708 } 709 710 DEFINE_TEST(test_continue_search_6) 711 { 712 static int ret; 713 static int ret2; 714 715 ret = return_zero(); 716 ret2 = return_zero(); 717 718 _SEH2_TRY 719 { 720 _SEH2_TRY 721 { 722 RaiseException(0xE00DEAD0, 0, 0, NULL); 723 ret = return_zero(); 724 ret2 = return_zero(); 725 } 726 _SEH2_EXCEPT(set_positive(&ret), EXCEPTION_CONTINUE_SEARCH) 727 { 728 ret = return_zero(); 729 ret2 = return_zero(); 730 } 731 _SEH2_END; 732 } 733 _SEH2_EXCEPT(set_positive(&ret2), EXCEPTION_EXECUTE_HANDLER) 734 { 735 ret = return_arg(ret); 736 ret2 = return_arg(ret2); 737 } 738 _SEH2_END; 739 740 return ret == return_positive() && ret2 == return_positive(); 741 } 742 743 DEFINE_TEST(test_execute_handler_12) 744 { 745 static int ret; 746 747 ret = return_zero(); 748 749 _SEH2_TRY 750 { 751 RaiseException(0xE00DEAD0, 0, 0, NULL); 752 ret = return_zero(); 753 } 754 _SEH2_EXCEPT(set_positive(&ret), 12345) 755 { 756 ret = return_arg(ret); 757 } 758 _SEH2_END; 759 760 return ret == return_positive(); 761 } 762 763 DEFINE_TEST(test_continue_execution_12) 764 { 765 static int ret; 766 767 ret = return_zero(); 768 769 _SEH2_TRY 770 { 771 RaiseException(0xE00DEAD0, 0, 0, NULL); 772 ret = return_arg(ret); 773 } 774 _SEH2_EXCEPT(set_positive(&ret), -12345) 775 { 776 ret = return_zero(); 777 } 778 _SEH2_END; 779 780 return ret == return_positive(); 781 } 782 //}}} 783 784 /* _SEH2_LEAVE *///{{{ 785 DEFINE_TEST(test_leave_1) 786 { 787 static int ret; 788 789 ret = return_zero(); 790 791 _SEH2_TRY 792 { 793 ret = return_positive(); 794 _SEH2_LEAVE; 795 ret = return_zero(); 796 } 797 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 798 { 799 ret = return_zero(); 800 } 801 _SEH2_END; 802 803 return ret == return_positive(); 804 } 805 806 DEFINE_TEST(test_leave_2) 807 { 808 static int ret; 809 810 ret = return_zero(); 811 812 _SEH2_TRY 813 { 814 ret = return_positive(); 815 _SEH2_LEAVE; 816 817 RaiseException(0xE00DEAD0, 0, 0, NULL); 818 ret = return_zero(); 819 } 820 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 821 { 822 ret = return_zero(); 823 } 824 _SEH2_END; 825 826 return ret == return_positive(); 827 } 828 829 DEFINE_TEST(test_leave_3) 830 { 831 static int ret; 832 833 ret = return_zero(); 834 835 _SEH2_TRY 836 { 837 ret = return_positive(); 838 839 if(return_one()) 840 _SEH2_LEAVE; 841 842 ret = return_zero(); 843 } 844 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 845 { 846 ret = return_zero(); 847 } 848 _SEH2_END; 849 850 return ret == return_positive(); 851 } 852 853 DEFINE_TEST(test_leave_4) 854 { 855 static int ret; 856 857 ret = return_zero(); 858 859 _SEH2_TRY 860 { 861 int i; 862 int n = return_one() + return_one(); 863 864 for(i = return_zero(); i < n; ++ i) 865 { 866 if(i == return_one()) 867 { 868 ret = return_positive(); 869 _SEH2_LEAVE; 870 } 871 } 872 873 ret = return_zero(); 874 } 875 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 876 { 877 ret = return_zero(); 878 } 879 _SEH2_END; 880 881 return ret == return_positive(); 882 } 883 884 DEFINE_TEST(test_leave_5) 885 { 886 static int ret; 887 888 ret = return_zero(); 889 890 _SEH2_TRY 891 { 892 switch(return_one()) 893 { 894 case 0: ret = return_zero(); 895 case 1: ret = return_positive(); _SEH2_LEAVE; 896 case 2: ret = return_zero(); 897 } 898 899 ret = return_zero(); 900 } 901 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 902 { 903 ret = return_zero(); 904 } 905 _SEH2_END; 906 907 return ret == return_positive(); 908 } 909 910 DEFINE_TEST(test_leave_6) 911 { 912 static int ret; 913 914 ret = return_zero(); 915 916 _SEH2_TRY 917 { 918 _SEH2_TRY 919 { 920 _SEH2_LEAVE; 921 } 922 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 923 { 924 ret = return_zero(); 925 } 926 _SEH2_END; 927 928 ret = return_positive(); 929 } 930 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 931 { 932 ret = return_zero(); 933 } 934 _SEH2_END; 935 936 return ret == return_positive(); 937 } 938 //}}} 939 940 /* _SEH2_YIELD() *///{{{ 941 static 942 int test_yield_1_helper(void) 943 { 944 _SEH2_TRY 945 { 946 _SEH2_YIELD(return return_positive()); 947 } 948 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 949 { 950 _SEH2_YIELD(return return_zero()); 951 } 952 _SEH2_END; 953 954 return return_zero(); 955 } 956 957 DEFINE_TEST(test_yield_1) 958 { 959 return test_yield_1_helper() == return_positive(); 960 } 961 962 static 963 int test_yield_2_helper(void) 964 { 965 _SEH2_TRY 966 { 967 RaiseException(0xE00DEAD0, 0, 0, NULL); 968 _SEH2_YIELD(return return_zero()); 969 } 970 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 971 { 972 _SEH2_YIELD(return return_positive()); 973 } 974 _SEH2_END; 975 976 return return_zero(); 977 } 978 979 DEFINE_TEST(test_yield_2) 980 { 981 return test_yield_2_helper() == return_positive(); 982 } 983 984 static 985 int test_yield_3_helper(void) 986 { 987 _SEH2_TRY 988 { 989 _SEH2_TRY 990 { 991 _SEH2_YIELD(return return_positive()); 992 } 993 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 994 { 995 _SEH2_YIELD(return return_zero()); 996 } 997 _SEH2_END; 998 999 _SEH2_YIELD(return return_zero()); 1000 } 1001 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1002 { 1003 _SEH2_YIELD(return return_zero()); 1004 } 1005 _SEH2_END; 1006 1007 return return_zero(); 1008 } 1009 1010 DEFINE_TEST(test_yield_3) 1011 { 1012 return test_yield_3_helper() == return_positive(); 1013 } 1014 1015 static 1016 int test_yield_4_helper(void) 1017 { 1018 _SEH2_TRY 1019 { 1020 _SEH2_TRY 1021 { 1022 RaiseException(0xE00DEAD0, 0, 0, NULL); 1023 _SEH2_YIELD(return return_zero()); 1024 } 1025 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1026 { 1027 _SEH2_YIELD(return return_positive()); 1028 } 1029 _SEH2_END; 1030 1031 _SEH2_YIELD(return return_zero()); 1032 } 1033 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1034 { 1035 _SEH2_YIELD(return return_zero()); 1036 } 1037 _SEH2_END; 1038 1039 return return_zero(); 1040 } 1041 1042 DEFINE_TEST(test_yield_4) 1043 { 1044 return test_yield_4_helper() == return_positive(); 1045 } 1046 1047 static int test_yield_5_ret; 1048 1049 static 1050 int test_yield_5_helper(void) 1051 { 1052 test_yield_5_ret = return_zero(); 1053 1054 _SEH2_TRY 1055 { 1056 _SEH2_YIELD(return return_positive()); 1057 } 1058 _SEH2_FINALLY 1059 { 1060 test_yield_5_ret = return_positive(); 1061 } 1062 _SEH2_END; 1063 1064 return return_zero(); 1065 } 1066 1067 DEFINE_TEST(test_yield_5) 1068 { 1069 return test_yield_5_helper() == return_positive() && test_yield_5_ret == return_positive(); 1070 } 1071 1072 static int test_yield_6_ret; 1073 1074 static 1075 int test_yield_6_helper(void) 1076 { 1077 test_yield_6_ret = return_zero(); 1078 1079 _SEH2_TRY 1080 { 1081 _SEH2_TRY 1082 { 1083 _SEH2_YIELD(return return_positive()); 1084 } 1085 _SEH2_FINALLY 1086 { 1087 test_yield_6_ret = return_positive(); 1088 } 1089 _SEH2_END; 1090 } 1091 _SEH2_FINALLY 1092 { 1093 test_yield_6_ret += return_one(); 1094 } 1095 _SEH2_END; 1096 1097 return return_zero(); 1098 } 1099 1100 DEFINE_TEST(test_yield_6) 1101 { 1102 return test_yield_6_helper() == return_positive() && test_yield_6_ret == return_positive() + return_one(); 1103 } 1104 //}}} 1105 1106 /* Termination blocks *///{{{ 1107 DEFINE_TEST(test_finally_1) 1108 { 1109 static int ret; 1110 1111 ret = return_zero(); 1112 1113 _SEH2_TRY 1114 { 1115 ret = return_arg(ret); 1116 } 1117 _SEH2_FINALLY 1118 { 1119 ret = return_positive(); 1120 } 1121 _SEH2_END; 1122 1123 return ret == return_positive(); 1124 } 1125 1126 DEFINE_TEST(test_finally_2) 1127 { 1128 static int ret; 1129 1130 ret = return_zero(); 1131 1132 _SEH2_TRY 1133 { 1134 ret = return_arg(ret); 1135 _SEH2_LEAVE; 1136 } 1137 _SEH2_FINALLY 1138 { 1139 ret = return_positive(); 1140 } 1141 _SEH2_END; 1142 1143 return ret == return_positive(); 1144 } 1145 1146 DEFINE_TEST(test_finally_3) 1147 { 1148 static int ret; 1149 1150 ret = return_zero(); 1151 1152 _SEH2_TRY 1153 { 1154 ret = return_arg(ret); 1155 _SEH2_YIELD(goto leave); 1156 } 1157 _SEH2_FINALLY 1158 { 1159 ret = return_positive(); 1160 } 1161 _SEH2_END; 1162 1163 leave: 1164 return ret == return_positive(); 1165 } 1166 1167 static int test_finally_4_ret; 1168 1169 static int test_finally_4_helper(void) 1170 { 1171 test_finally_4_ret = return_zero(); 1172 1173 _SEH2_TRY 1174 { 1175 test_finally_4_ret = return_arg(test_finally_4_ret); 1176 _SEH2_YIELD(return return_positive()); 1177 } 1178 _SEH2_FINALLY 1179 { 1180 test_finally_4_ret = return_positive(); 1181 } 1182 _SEH2_END; 1183 1184 return return_zero(); 1185 } 1186 1187 DEFINE_TEST(test_finally_4) 1188 { 1189 return test_finally_4_helper() == return_positive() && test_finally_4_ret; 1190 } 1191 1192 DEFINE_TEST(test_finally_5) 1193 { 1194 static int ret; 1195 1196 ret = return_zero(); 1197 1198 _SEH2_TRY 1199 { 1200 _SEH2_TRY 1201 { 1202 RaiseException(0xE00DEAD0, 0, 0, NULL); 1203 ret = return_zero(); 1204 } 1205 _SEH2_FINALLY 1206 { 1207 ret = return_positive(); 1208 } 1209 _SEH2_END; 1210 } 1211 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1212 { 1213 ret = return_arg(ret); 1214 } 1215 _SEH2_END; 1216 1217 return ret == return_positive(); 1218 } 1219 1220 DEFINE_TEST(test_finally_6) 1221 { 1222 static int ret; 1223 1224 ret = return_zero(); 1225 1226 _SEH2_TRY 1227 { 1228 _SEH2_TRY 1229 { 1230 ret = return_arg(ret); 1231 } 1232 _SEH2_FINALLY 1233 { 1234 if(ret == return_zero()) 1235 ret = return_positive(); 1236 } 1237 _SEH2_END; 1238 } 1239 _SEH2_FINALLY 1240 { 1241 if(ret == return_positive()) 1242 ret = return_positive() + return_one(); 1243 } 1244 _SEH2_END; 1245 1246 return ret == return_positive() + return_one(); 1247 } 1248 1249 DEFINE_TEST(test_finally_7) 1250 { 1251 static int ret; 1252 1253 ret = return_zero(); 1254 1255 _SEH2_TRY 1256 { 1257 _SEH2_TRY 1258 { 1259 ret = return_arg(ret); 1260 _SEH2_LEAVE; 1261 } 1262 _SEH2_FINALLY 1263 { 1264 if(ret == return_zero()) 1265 ret = return_positive(); 1266 } 1267 _SEH2_END; 1268 } 1269 _SEH2_FINALLY 1270 { 1271 if(ret == return_positive()) 1272 ret = return_positive() + return_one(); 1273 } 1274 _SEH2_END; 1275 1276 return ret == return_positive() + return_one(); 1277 } 1278 1279 DEFINE_TEST(test_finally_8) 1280 { 1281 static int ret; 1282 1283 ret = return_zero(); 1284 1285 _SEH2_TRY 1286 { 1287 _SEH2_TRY 1288 { 1289 ret = return_arg(ret); 1290 _SEH2_YIELD(goto leave); 1291 } 1292 _SEH2_FINALLY 1293 { 1294 if(ret == return_zero()) 1295 ret = return_positive(); 1296 } 1297 _SEH2_END; 1298 } 1299 _SEH2_FINALLY 1300 { 1301 if(ret == return_positive()) 1302 ret = return_positive() + return_one(); 1303 } 1304 _SEH2_END; 1305 1306 leave: 1307 return ret == return_positive() + return_one(); 1308 } 1309 1310 static int test_finally_9_ret; 1311 1312 static int test_finally_9_helper(void) 1313 { 1314 test_finally_9_ret = return_zero(); 1315 1316 _SEH2_TRY 1317 { 1318 _SEH2_TRY 1319 { 1320 test_finally_9_ret = return_arg(test_finally_9_ret); 1321 _SEH2_YIELD(return return_positive()); 1322 } 1323 _SEH2_FINALLY 1324 { 1325 if(test_finally_9_ret == return_zero()) 1326 test_finally_9_ret = return_positive(); 1327 } 1328 _SEH2_END; 1329 } 1330 _SEH2_FINALLY 1331 { 1332 if(test_finally_9_ret == return_positive()) 1333 test_finally_9_ret = return_positive() + return_one(); 1334 } 1335 _SEH2_END; 1336 1337 return return_zero(); 1338 } 1339 1340 DEFINE_TEST(test_finally_9) 1341 { 1342 return test_finally_9_helper() == return_positive() && test_finally_9_ret == return_positive() + return_one(); 1343 } 1344 1345 DEFINE_TEST(test_finally_10) 1346 { 1347 static int ret; 1348 1349 ret = return_zero(); 1350 1351 _SEH2_TRY 1352 { 1353 _SEH2_TRY 1354 { 1355 _SEH2_TRY 1356 { 1357 RaiseException(0xE00DEAD0, 0, 0, NULL); 1358 ret = return_zero(); 1359 } 1360 _SEH2_FINALLY 1361 { 1362 if(ret == return_zero()) 1363 ret = return_positive(); 1364 } 1365 _SEH2_END; 1366 } 1367 _SEH2_FINALLY 1368 { 1369 if(ret == return_positive()) 1370 ret = return_positive() + return_one(); 1371 } 1372 _SEH2_END; 1373 } 1374 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1375 { 1376 ret = return_arg(ret); 1377 } 1378 _SEH2_END; 1379 1380 return ret == return_positive() + return_one(); 1381 } 1382 1383 DEFINE_TEST(test_finally_11) 1384 { 1385 static int ret; 1386 1387 ret = return_zero(); 1388 1389 _SEH2_TRY 1390 { 1391 _SEH2_TRY 1392 { 1393 _SEH2_TRY 1394 { 1395 ret = return_arg(ret); 1396 } 1397 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1398 { 1399 ret = return_zero(); 1400 } 1401 _SEH2_END; 1402 } 1403 _SEH2_FINALLY 1404 { 1405 ret = return_positive(); 1406 RaiseException(0xE00DEAD0, 0, 0, NULL); 1407 ret = return_zero(); 1408 } 1409 _SEH2_END; 1410 } 1411 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1412 { 1413 if(ret == return_positive()) 1414 ret += return_one(); 1415 } 1416 _SEH2_END; 1417 1418 return ret == return_positive() + return_one(); 1419 } 1420 1421 DEFINE_TEST(test_finally_12) 1422 { 1423 static int ret; 1424 1425 ret = return_zero(); 1426 1427 _SEH2_TRY 1428 { 1429 _SEH2_TRY 1430 { 1431 _SEH2_TRY 1432 { 1433 ret = return_arg(ret); 1434 } 1435 _SEH2_FINALLY 1436 { 1437 ret = return_positive(); 1438 RaiseException(0xE00DEAD0, 0, 0, NULL); 1439 ret = return_zero(); 1440 } 1441 _SEH2_END; 1442 } 1443 _SEH2_FINALLY 1444 { 1445 if(ret == return_positive()) 1446 ret += return_one(); 1447 } 1448 _SEH2_END; 1449 } 1450 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1451 { 1452 if(ret == return_positive() + return_one()) 1453 ret += return_one(); 1454 } 1455 _SEH2_END; 1456 1457 return ret == return_positive() + return_one() + return_one(); 1458 } 1459 1460 static int test_finally_13_ret; 1461 1462 static 1463 void test_finally_13_helper(void) 1464 { 1465 test_finally_13_ret = return_zero(); 1466 1467 _SEH2_TRY 1468 { 1469 _SEH2_TRY 1470 { 1471 test_finally_13_ret = return_positive(); 1472 _SEH2_YIELD(return); 1473 test_finally_13_ret = return_zero(); 1474 } 1475 _SEH2_FINALLY 1476 { 1477 if(test_finally_13_ret == return_positive()) 1478 test_finally_13_ret += return_one(); 1479 } 1480 _SEH2_END; 1481 } 1482 _SEH2_FINALLY 1483 { 1484 if(test_finally_13_ret == return_positive() + return_one()) 1485 test_finally_13_ret += return_one(); 1486 1487 RaiseException(0xE00DEAD0, 0, 0, NULL); 1488 test_finally_13_ret = return_zero(); 1489 } 1490 _SEH2_END; 1491 1492 test_finally_13_ret = return_zero(); 1493 } 1494 1495 DEFINE_TEST(test_finally_13) 1496 { 1497 static int ret; 1498 1499 ret = return_zero(); 1500 1501 _SEH2_TRY 1502 { 1503 ret = return_arg(ret); 1504 test_finally_13_helper(); 1505 ret = return_zero(); 1506 } 1507 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1508 { 1509 ret = return_positive(); 1510 } 1511 _SEH2_END; 1512 1513 return ret == return_positive() && test_finally_13_ret == return_positive() + return_one() + return_one(); 1514 } 1515 1516 static int test_finally_14_ret; 1517 1518 static 1519 void test_finally_14_helper(void) 1520 { 1521 test_finally_14_ret = return_zero(); 1522 1523 _SEH2_TRY 1524 { 1525 _SEH2_TRY 1526 { 1527 _SEH2_TRY 1528 { 1529 test_finally_14_ret = return_positive(); 1530 RaiseException(0xE00DEAD0, 0, 0, NULL); 1531 test_finally_14_ret = return_zero(); 1532 } 1533 _SEH2_FINALLY 1534 { 1535 if(test_finally_14_ret == return_positive()) 1536 test_finally_14_ret += return_one(); 1537 } 1538 _SEH2_END; 1539 } 1540 _SEH2_FINALLY 1541 { 1542 if(test_finally_14_ret == return_positive() + return_one()) 1543 test_finally_14_ret += return_one(); 1544 1545 RaiseException(0xE00DEAD0, 0, 0, NULL); 1546 test_finally_14_ret = return_zero(); 1547 } 1548 _SEH2_END; 1549 } 1550 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1551 { 1552 if(test_finally_14_ret == return_positive() + return_one() + return_one()) 1553 test_finally_14_ret += return_one(); 1554 } 1555 _SEH2_END; 1556 1557 test_finally_14_ret = return_arg(test_finally_14_ret); 1558 } 1559 1560 DEFINE_TEST(test_finally_14) 1561 { 1562 static int ret; 1563 1564 ret = return_zero(); 1565 1566 _SEH2_TRY 1567 { 1568 ret = return_arg(ret); 1569 test_finally_14_helper(); 1570 ret = return_positive(); 1571 } 1572 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1573 { 1574 ret = return_zero(); 1575 } 1576 _SEH2_END; 1577 1578 return ret == return_positive() && test_finally_14_ret == return_positive() + return_one() + return_one() + return_one(); 1579 } 1580 //}}} 1581 1582 /* _SEH2_GetExceptionInformation() *///{{{ 1583 static 1584 int verify_xpointers(struct _EXCEPTION_POINTERS * ep, DWORD code, DWORD flags, DWORD argc, const ULONG_PTR * argv, int * ret, int filter) 1585 { 1586 *ret = 1587 ep && 1588 ep->ExceptionRecord && 1589 ep->ContextRecord && 1590 ep->ExceptionRecord->ExceptionCode == code && 1591 ep->ExceptionRecord->ExceptionFlags == flags && 1592 ep->ExceptionRecord->NumberParameters == argc && 1593 (argv || !argc) && 1594 memcmp(ep->ExceptionRecord->ExceptionInformation, argv, sizeof(argv[0]) * argc) == 0; 1595 1596 if(*ret) 1597 *ret = return_positive(); 1598 1599 return filter; 1600 } 1601 1602 DEFINE_TEST(test_xpointers_1) 1603 { 1604 static int ret; 1605 1606 ret = return_zero(); 1607 1608 _SEH2_TRY 1609 { 1610 RaiseException(0xE00DEAD0, 0, 0, NULL); 1611 } 1612 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, NULL, &ret, EXCEPTION_EXECUTE_HANDLER)) 1613 { 1614 ret = return_arg(ret); 1615 } 1616 _SEH2_END; 1617 1618 return ret == return_positive(); 1619 } 1620 1621 DEFINE_TEST(test_xpointers_2) 1622 { 1623 static int ret; 1624 1625 ret = return_zero(); 1626 1627 _SEH2_TRY 1628 { 1629 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL); 1630 } 1631 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL, &ret, EXCEPTION_EXECUTE_HANDLER)) 1632 { 1633 ret = return_arg(ret); 1634 } 1635 _SEH2_END; 1636 1637 return ret == return_positive(); 1638 } 1639 1640 DEFINE_TEST(test_xpointers_3) 1641 { 1642 static int ret; 1643 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1644 1645 ret = return_zero(); 1646 1647 _SEH2_TRY 1648 { 1649 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args); 1650 } 1651 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args, &ret, EXCEPTION_EXECUTE_HANDLER)) 1652 { 1653 ret = return_arg(ret); 1654 } 1655 _SEH2_END; 1656 1657 return ret == return_positive(); 1658 } 1659 1660 DEFINE_TEST(test_xpointers_4) 1661 { 1662 static int ret; 1663 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1664 1665 ret = return_zero(); 1666 1667 _SEH2_TRY 1668 { 1669 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args); 1670 } 1671 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args, &ret, EXCEPTION_EXECUTE_HANDLER)) 1672 { 1673 ret = return_arg(ret); 1674 } 1675 _SEH2_END; 1676 1677 return ret == return_positive(); 1678 } 1679 1680 DEFINE_TEST(test_xpointers_5) 1681 { 1682 static int ret; 1683 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1684 1685 ret = return_zero(); 1686 1687 _SEH2_TRY 1688 { 1689 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args); 1690 } 1691 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args, &ret, EXCEPTION_EXECUTE_HANDLER)) 1692 { 1693 ret = return_arg(ret); 1694 } 1695 _SEH2_END; 1696 1697 return ret == return_positive(); 1698 } 1699 1700 DEFINE_TEST(test_xpointers_6) 1701 { 1702 static int ret; 1703 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1704 1705 ret = return_zero(); 1706 1707 _SEH2_TRY 1708 { 1709 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args); 1710 } 1711 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args, &ret, EXCEPTION_EXECUTE_HANDLER)) 1712 { 1713 ret = return_arg(ret); 1714 } 1715 _SEH2_END; 1716 1717 return ret == return_positive(); 1718 } 1719 1720 DEFINE_TEST(test_xpointers_7) 1721 { 1722 static int ret; 1723 1724 ret = return_zero(); 1725 1726 _SEH2_TRY 1727 { 1728 RaiseException(0xE00DEAD0, 0, 0, NULL); 1729 ret = return_arg(ret); 1730 } 1731 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, NULL, &ret, EXCEPTION_CONTINUE_EXECUTION)) 1732 { 1733 ret = return_zero(); 1734 } 1735 _SEH2_END; 1736 1737 return ret == return_positive(); 1738 } 1739 1740 DEFINE_TEST(test_xpointers_8) 1741 { 1742 static int ret; 1743 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1744 1745 ret = return_zero(); 1746 1747 _SEH2_TRY 1748 { 1749 RaiseException(0xE00DEAD0, 0, 0, args); 1750 ret = return_arg(ret); 1751 } 1752 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, args, &ret, EXCEPTION_CONTINUE_EXECUTION)) 1753 { 1754 ret = return_zero(); 1755 } 1756 _SEH2_END; 1757 1758 return ret == return_positive(); 1759 } 1760 1761 DEFINE_TEST(test_xpointers_9) 1762 { 1763 static int ret; 1764 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1765 1766 ret = return_zero(); 1767 1768 _SEH2_TRY 1769 { 1770 RaiseException(0xE00DEAD0, 0, 1, args); 1771 ret = return_arg(ret); 1772 } 1773 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 1, args, &ret, EXCEPTION_CONTINUE_EXECUTION)) 1774 { 1775 ret = return_zero(); 1776 } 1777 _SEH2_END; 1778 1779 return ret == return_positive(); 1780 } 1781 1782 DEFINE_TEST(test_xpointers_10) 1783 { 1784 static int ret; 1785 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1786 1787 ret = return_zero(); 1788 1789 _SEH2_TRY 1790 { 1791 RaiseException(0xE00DEAD0, 0, 2, args); 1792 ret = return_arg(ret); 1793 } 1794 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 2, args, &ret, EXCEPTION_CONTINUE_EXECUTION)) 1795 { 1796 ret = return_zero(); 1797 } 1798 _SEH2_END; 1799 1800 return ret == return_positive(); 1801 } 1802 1803 DEFINE_TEST(test_xpointers_11) 1804 { 1805 static int ret; 1806 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1807 1808 ret = return_zero(); 1809 1810 _SEH2_TRY 1811 { 1812 RaiseException(0xE00DEAD0, 0, 3, args); 1813 ret = return_arg(ret); 1814 } 1815 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 3, args, &ret, EXCEPTION_CONTINUE_EXECUTION)) 1816 { 1817 ret = return_zero(); 1818 } 1819 _SEH2_END; 1820 1821 return ret == return_positive(); 1822 } 1823 1824 DEFINE_TEST(test_xpointers_12) 1825 { 1826 static int ret; 1827 1828 ret = return_zero(); 1829 1830 _SEH2_TRY 1831 { 1832 _SEH2_TRY 1833 { 1834 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL); 1835 } 1836 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL, &ret, EXCEPTION_CONTINUE_SEARCH)) 1837 { 1838 ret = return_zero(); 1839 } 1840 _SEH2_END; 1841 } 1842 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1843 { 1844 ret = return_arg(ret); 1845 } 1846 _SEH2_END; 1847 1848 return ret == return_positive(); 1849 } 1850 1851 DEFINE_TEST(test_xpointers_13) 1852 { 1853 static int ret; 1854 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1855 1856 ret = return_zero(); 1857 1858 _SEH2_TRY 1859 { 1860 _SEH2_TRY 1861 { 1862 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args); 1863 } 1864 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args, &ret, EXCEPTION_CONTINUE_SEARCH)) 1865 { 1866 ret = return_zero(); 1867 } 1868 _SEH2_END; 1869 } 1870 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1871 { 1872 ret = return_arg(ret); 1873 } 1874 _SEH2_END; 1875 1876 return ret == return_positive(); 1877 } 1878 1879 DEFINE_TEST(test_xpointers_14) 1880 { 1881 static int ret; 1882 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1883 1884 ret = return_zero(); 1885 1886 _SEH2_TRY 1887 { 1888 _SEH2_TRY 1889 { 1890 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args); 1891 } 1892 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args, &ret, EXCEPTION_CONTINUE_SEARCH)) 1893 { 1894 ret = return_zero(); 1895 } 1896 _SEH2_END; 1897 } 1898 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1899 { 1900 ret = return_arg(ret); 1901 } 1902 _SEH2_END; 1903 1904 return ret == return_positive(); 1905 } 1906 1907 DEFINE_TEST(test_xpointers_15) 1908 { 1909 static int ret; 1910 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1911 1912 ret = return_zero(); 1913 1914 _SEH2_TRY 1915 { 1916 _SEH2_TRY 1917 { 1918 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args); 1919 } 1920 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args, &ret, EXCEPTION_CONTINUE_SEARCH)) 1921 { 1922 ret = return_zero(); 1923 } 1924 _SEH2_END; 1925 } 1926 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1927 { 1928 ret = return_arg(ret); 1929 } 1930 _SEH2_END; 1931 1932 return ret == return_positive(); 1933 } 1934 1935 DEFINE_TEST(test_xpointers_16) 1936 { 1937 static int ret; 1938 static const ULONG_PTR args[] = { 1, 2, 12345 }; 1939 1940 ret = return_zero(); 1941 1942 _SEH2_TRY 1943 { 1944 _SEH2_TRY 1945 { 1946 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args); 1947 } 1948 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args, &ret, EXCEPTION_CONTINUE_SEARCH)) 1949 { 1950 ret = return_zero(); 1951 } 1952 _SEH2_END; 1953 } 1954 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1955 { 1956 ret = return_arg(ret); 1957 } 1958 _SEH2_END; 1959 1960 return ret == return_positive(); 1961 } 1962 //}}} 1963 1964 /* _SEH2_GetExceptionCode() *///{{{ 1965 static 1966 int verify_xcode(int code, int xcode, int * ret, int filter) 1967 { 1968 *ret = code == xcode; 1969 1970 if(*ret) 1971 *ret = return_positive(); 1972 1973 return filter; 1974 } 1975 1976 DEFINE_TEST(test_xcode_1) 1977 { 1978 static int ret; 1979 1980 ret = return_zero(); 1981 1982 _SEH2_TRY 1983 { 1984 RaiseException(0xE00DEAD0, 0, 0, NULL); 1985 ret = return_zero(); 1986 } 1987 _SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_EXECUTE_HANDLER)) 1988 { 1989 ret = return_arg(ret); 1990 } 1991 _SEH2_END; 1992 1993 return ret == return_positive(); 1994 } 1995 1996 DEFINE_TEST(test_xcode_2) 1997 { 1998 static int ret; 1999 2000 ret = return_zero(); 2001 2002 _SEH2_TRY 2003 { 2004 RaiseException(0xE00DEAD0, 0, 0, NULL); 2005 ret = return_arg(ret); 2006 } 2007 _SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_CONTINUE_EXECUTION)) 2008 { 2009 ret = return_zero(); 2010 } 2011 _SEH2_END; 2012 2013 return ret == return_positive(); 2014 } 2015 2016 DEFINE_TEST(test_xcode_3) 2017 { 2018 static int ret; 2019 2020 ret = return_zero(); 2021 2022 _SEH2_TRY 2023 { 2024 _SEH2_TRY 2025 { 2026 RaiseException(0xE00DEAD0, 0, 0, NULL); 2027 ret = return_zero(); 2028 } 2029 _SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_CONTINUE_SEARCH)) 2030 { 2031 ret = return_zero(); 2032 } 2033 _SEH2_END; 2034 } 2035 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2036 { 2037 ret = return_arg(ret); 2038 } 2039 _SEH2_END; 2040 2041 return ret == return_positive(); 2042 } 2043 //}}} 2044 2045 /* _SEH2_AbnormalTermination() *///{{{ 2046 DEFINE_TEST(test_abnorm_1) 2047 { 2048 static int ret; 2049 2050 ret = return_zero(); 2051 2052 _SEH2_TRY 2053 { 2054 ret = return_arg(ret); 2055 } 2056 _SEH2_FINALLY 2057 { 2058 ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive(); 2059 } 2060 _SEH2_END; 2061 2062 return ret == return_positive(); 2063 } 2064 2065 DEFINE_TEST(test_abnorm_2) 2066 { 2067 static int ret; 2068 2069 ret = return_zero(); 2070 2071 _SEH2_TRY 2072 { 2073 _SEH2_LEAVE; 2074 } 2075 _SEH2_FINALLY 2076 { 2077 ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive(); 2078 } 2079 _SEH2_END; 2080 2081 return ret == return_positive(); 2082 } 2083 2084 DEFINE_TEST(test_abnorm_3) 2085 { 2086 static int ret; 2087 2088 ret = return_zero(); 2089 2090 _SEH2_TRY 2091 { 2092 _SEH2_YIELD(goto leave); 2093 } 2094 _SEH2_FINALLY 2095 { 2096 ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero(); 2097 } 2098 _SEH2_END; 2099 2100 leave: 2101 return ret == return_positive(); 2102 } 2103 2104 DEFINE_TEST(test_abnorm_4) 2105 { 2106 static int ret; 2107 2108 ret = return_zero(); 2109 2110 _SEH2_TRY 2111 { 2112 _SEH2_TRY 2113 { 2114 RaiseException(0xE00DEAD0, 0, 0, NULL); 2115 ret = return_zero(); 2116 } 2117 _SEH2_FINALLY 2118 { 2119 ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero(); 2120 } 2121 _SEH2_END; 2122 } 2123 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2124 { 2125 ret = return_arg(ret); 2126 } 2127 _SEH2_END; 2128 2129 return ret == return_positive(); 2130 } 2131 2132 DEFINE_TEST(test_abnorm_5) 2133 { 2134 static int ret; 2135 2136 ret = return_zero(); 2137 2138 _SEH2_TRY 2139 { 2140 _SEH2_TRY 2141 { 2142 ret = return_arg(ret); 2143 } 2144 _SEH2_FINALLY 2145 { 2146 ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive(); 2147 } 2148 _SEH2_END; 2149 } 2150 _SEH2_FINALLY 2151 { 2152 ret = ret == return_positive() && !_SEH2_AbnormalTermination() ? return_positive() + return_one() : ret; 2153 } 2154 _SEH2_END; 2155 2156 return ret == return_positive() + return_one(); 2157 } 2158 2159 DEFINE_TEST(test_abnorm_6) 2160 { 2161 static int ret; 2162 2163 ret = return_zero(); 2164 2165 _SEH2_TRY 2166 { 2167 _SEH2_TRY 2168 { 2169 _SEH2_LEAVE; 2170 } 2171 _SEH2_FINALLY 2172 { 2173 ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive(); 2174 } 2175 _SEH2_END; 2176 } 2177 _SEH2_FINALLY 2178 { 2179 ret = ret == return_positive() && !_SEH2_AbnormalTermination() ? return_positive() + return_one() : ret; 2180 } 2181 _SEH2_END; 2182 2183 return ret == return_positive() + return_one(); 2184 } 2185 2186 DEFINE_TEST(test_abnorm_7) 2187 { 2188 static int ret; 2189 2190 ret = return_zero(); 2191 2192 _SEH2_TRY 2193 { 2194 _SEH2_TRY 2195 { 2196 _SEH2_YIELD(goto leave); 2197 } 2198 _SEH2_FINALLY 2199 { 2200 ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero(); 2201 } 2202 _SEH2_END; 2203 } 2204 _SEH2_FINALLY 2205 { 2206 ret = ret == return_positive() && _SEH2_AbnormalTermination() ? return_positive() + return_one() : ret; 2207 } 2208 _SEH2_END; 2209 2210 leave: 2211 return ret == return_positive() + return_one(); 2212 } 2213 2214 DEFINE_TEST(test_abnorm_8) 2215 { 2216 static int ret; 2217 2218 ret = return_zero(); 2219 2220 _SEH2_TRY 2221 { 2222 _SEH2_TRY 2223 { 2224 _SEH2_TRY 2225 { 2226 RaiseException(0xE00DEAD0, 0, 0, NULL); 2227 ret = return_zero(); 2228 } 2229 _SEH2_FINALLY 2230 { 2231 ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero(); 2232 } 2233 _SEH2_END; 2234 } 2235 _SEH2_FINALLY 2236 { 2237 ret = ret == return_positive() && _SEH2_AbnormalTermination() ? return_positive() + return_one() : ret; 2238 } 2239 _SEH2_END; 2240 } 2241 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2242 { 2243 ret = return_arg(ret); 2244 } 2245 _SEH2_END; 2246 2247 return ret == return_positive() + return_one(); 2248 } 2249 //}}} 2250 2251 /* Use of local variables from _SEH2_EXCEPT(...) and _SEH2_FINALLY { ... } *///{{{ 2252 DEFINE_TEST(test_nested_locals_1) 2253 { 2254 int var1 = return_one(); 2255 2256 _SEH2_TRY 2257 { 2258 RaiseException(0xE00DEAD0, 0, 0, 0); 2259 } 2260 _SEH2_EXCEPT((var1 = (var1 == return_one() ? return_positive() : var1)), EXCEPTION_EXECUTE_HANDLER) 2261 { 2262 if(var1 == return_positive()) 2263 var1 = return_positive() + 1; 2264 } 2265 _SEH2_END; 2266 2267 return var1 == return_positive() + 1; 2268 } 2269 2270 DEFINE_TEST(test_nested_locals_2) 2271 { 2272 int var1 = return_positive(); 2273 2274 _SEH2_TRY 2275 { 2276 } 2277 _SEH2_FINALLY 2278 { 2279 if(var1 == return_positive()) 2280 var1 = return_positive() + 1; 2281 } 2282 _SEH2_END; 2283 2284 return var1 == return_positive() + 1; 2285 } 2286 2287 DEFINE_TEST(test_nested_locals_3) 2288 { 2289 int var1 = return_zero(); 2290 2291 _SEH2_TRY 2292 { 2293 _SEH2_TRY 2294 { 2295 var1 = return_one(); 2296 RaiseException(0xE00DEAD0, 0, 0, 0); 2297 } 2298 _SEH2_FINALLY 2299 { 2300 if(var1 == return_one()) 2301 var1 = return_positive(); 2302 } 2303 _SEH2_END; 2304 } 2305 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2306 { 2307 if(var1 == return_positive()) 2308 var1 = return_positive() + 1; 2309 } 2310 _SEH2_END; 2311 2312 return var1 == return_positive() + 1; 2313 } 2314 //}}} 2315 2316 /* System support *///{{{ 2317 // TODO 2318 //}}} 2319 2320 /* CPU faults *///{{{ 2321 // TODO 2322 //}}} 2323 2324 /* Past bugs, to detect regressions *///{{{ 2325 /* #4004: volatile registers clobbered when catching across frames (originally misreported) *///{{{ 2326 static 2327 void test_bug_4004_helper_1(void) 2328 { 2329 int i1, i2, i3; 2330 2331 i1 = return_positive(); 2332 i2 = return_positive(); 2333 i3 = return_positive(); 2334 (void)return_arg(i1 + i2 + i3); 2335 2336 _SEH2_TRY 2337 { 2338 RaiseException(0xE00DEAD0, 0, 0, NULL); 2339 } 2340 _SEH2_FINALLY 2341 { 2342 } 2343 _SEH2_END; 2344 } 2345 2346 static 2347 void test_bug_4004_helper_2(void) 2348 { 2349 _SEH2_TRY 2350 { 2351 test_bug_4004_helper_1(); 2352 } 2353 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2354 { 2355 } 2356 _SEH2_END; 2357 } 2358 2359 DEFINE_TEST(test_bug_4004) 2360 { 2361 int i1, i2, i3; 2362 2363 i1 = return_positive(); 2364 i2 = return_positive(); 2365 i3 = return_positive(); 2366 2367 test_bug_4004_helper_2(); 2368 2369 return return_arg(i1) + return_arg(i2) + return_arg(i3) == return_positive() * 3; 2370 } 2371 //}}} 2372 2373 /* #4663: *///{{{ 2374 DEFINE_TEST(test_bug_4663) 2375 { 2376 int i1, i2; 2377 2378 i1 = return_positive(); 2379 i2 = return_positive(); 2380 2381 _SEH2_TRY 2382 { 2383 _SEH2_TRY 2384 { 2385 RaiseException(0xE00DEAD0, 0, 0, 0); 2386 } 2387 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2388 { 2389 if (i1 == return_positive()) 2390 { 2391 i1 = return_positive() + 1; 2392 } 2393 } 2394 _SEH2_END; 2395 2396 if (i1 == return_positive() + 1) 2397 { 2398 i1 = return_negative(); 2399 RaiseException(0xE00DEAD0, 0, 0, 0); 2400 } 2401 } 2402 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2403 { 2404 i2 = return_negative(); 2405 } 2406 _SEH2_END; 2407 2408 return ((i1 == return_negative()) && (i2 == return_negative())); 2409 } 2410 //}}} 2411 //}}} 2412 2413 DEFINE_TEST(test_unvolatile) 2414 { 2415 int val = 0; 2416 2417 _SEH2_TRY 2418 { 2419 val = return_one(); 2420 *((char*)(intptr_t)0xc0000000) = 0; 2421 } 2422 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2423 { 2424 val = val + 3; 2425 } 2426 _SEH2_END; 2427 2428 return (val == 4); 2429 } 2430 2431 DEFINE_TEST(test_unvolatile_2) 2432 { 2433 int val = 0; 2434 2435 _SEH2_TRY 2436 { 2437 val = 1; 2438 *((char*)(intptr_t)0xc0000000) = 0; 2439 val = 2; 2440 } 2441 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2442 { 2443 val = val + 3; 2444 } 2445 _SEH2_END; 2446 2447 return (val == 3) || (val == 4) || (val == 5); 2448 } 2449 2450 /* This test is mainly for documentation purpose. As can be seen it doesn't 2451 provide a satisfying result. In fact the compiler could do even more 2452 crazy things like reusing val1 between the assignment to 0 and the last 2453 assignment to 3. This DOES happen with C++ and it's NOT a PSEH bug, but 2454 rather an unavoidable consequence of how the compiler works. 2455 The conclusion: Do not use assignments to a variable inside a __try block 2456 that is being used later inside the __except block, unless it is declared 2457 volatile! */ 2458 #ifndef __cplusplus 2459 DEFINE_TEST(test_unvolatile_3) 2460 { 2461 register int val1 = 0, val2 = 0; 2462 2463 _SEH2_TRY 2464 { 2465 val1 = 1; 2466 2467 _SEH2_TRY 2468 { 2469 val2 = 1; 2470 *((char*)(intptr_t)0xc0000000) = 0; 2471 val2 = 2; 2472 } 2473 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2474 { 2475 val2 |= 4; 2476 } 2477 _SEH2_END; 2478 2479 val1 = 2; 2480 *((int*)(intptr_t)0xc0000000) = 1; 2481 val1 = 3; 2482 } 2483 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2484 { 2485 val1 = val1 * val2; 2486 } 2487 _SEH2_END; 2488 2489 /* The expected case */ 2490 if ((val1 == 10) && (val2 == 5)) 2491 return TRUE; 2492 2493 /* The compiler can optimize away "val1 = 1" and "val1 = 2" and 2494 only use the last "val1 = 3", in this case val1 is still 0 2495 when the outer exception handler kicks in */ 2496 if ((val1 == 0) && (val2 == 5)) 2497 return TRUE; 2498 2499 /* Same as above, but this time val2 optimized away */ 2500 if (((val1 == 8) && (val2 == 4)) || 2501 ((val1 == 0) && (val2 == 4))) 2502 return TRUE; 2503 2504 return FALSE; 2505 } 2506 #endif // __cplusplus 2507 2508 DEFINE_TEST(test_unvolatile_4) 2509 { 2510 unsigned result = 0xdeadbeef; 2511 2512 _SEH2_TRY 2513 { 2514 *(char*)(intptr_t)0x80000000 = 1; 2515 } 2516 _SEH2_EXCEPT(result == 0xdeadbeef) 2517 { 2518 result = 2; 2519 } 2520 _SEH2_END; 2521 2522 result = (result == 0xdeadbeef) ? 0 : result + 1; 2523 2524 return result == 3; 2525 } 2526 2527 DEFINE_TEST(test_finally_goto) 2528 { 2529 volatile int val = 0; 2530 2531 _SEH2_TRY 2532 { 2533 val |= 1; 2534 _SEH2_TRY 2535 { 2536 val |= 2; 2537 goto next; 2538 } 2539 _SEH2_FINALLY 2540 { 2541 val |= 4; 2542 *((char*)(intptr_t)0xdeadc0de) = 0; 2543 val |= 8; 2544 } 2545 _SEH2_END; 2546 2547 val |= 16; 2548 next: 2549 val |= 32; 2550 *((char*)(intptr_t)0xdeadc0de) = 0; 2551 val |= 64; 2552 } 2553 _SEH2_EXCEPT(1) 2554 { 2555 val |= 128; 2556 } 2557 _SEH2_END; 2558 2559 return (val == (128|4|2|1)); 2560 } 2561 2562 DEFINE_TEST(test_nested_exception) 2563 { 2564 volatile int val = 0; 2565 2566 _SEH2_TRY 2567 { 2568 val |= 1; 2569 _SEH2_TRY 2570 { 2571 val |= 2; 2572 *((char*)(intptr_t)0xdeadc0de) = 0; 2573 val |= 4; 2574 } 2575 _SEH2_EXCEPT(1) 2576 { 2577 val |= 8; 2578 *((char*)(intptr_t)0xdeadc0de) = 0; 2579 val |= 16; 2580 } 2581 _SEH2_END; 2582 2583 val |= 32; 2584 *((char*)(intptr_t)0xdeadc0de) = 0; 2585 val |= 64; 2586 } 2587 _SEH2_EXCEPT(1) 2588 { 2589 val |= 128; 2590 } 2591 _SEH2_END; 2592 2593 return (val == (1|2|8|128)); 2594 } 2595 2596 static 2597 LONG WINAPI unhandled_exception(PEXCEPTION_POINTERS ExceptionInfo) 2598 { 2599 trace("unhandled exception %08lX thrown from %p\n", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress); 2600 return EXCEPTION_CONTINUE_SEARCH; 2601 } 2602 2603 #if defined(_M_IX86) 2604 struct volatile_context 2605 { 2606 void * esp; 2607 void * ebp; 2608 void * ebx; 2609 void * esi; 2610 void * edi; 2611 }; 2612 #else 2613 struct volatile_context 2614 { 2615 int _ignore; 2616 }; 2617 #endif 2618 2619 static 2620 DECLSPEC_NOINLINE 2621 int sanity_check(int ret, struct volatile_context * before, struct volatile_context * after) 2622 { 2623 if(ret && memcmp(before, after, sizeof(*before))) 2624 { 2625 trace("volatile context corrupted\n"); 2626 return 0; 2627 } 2628 2629 return ret; 2630 } 2631 2632 #ifndef _PSEH3_H_ 2633 static 2634 int passthrough_handler(struct _EXCEPTION_RECORD * e, void * f, struct _CONTEXT * c, void * d) 2635 { 2636 return ExceptionContinueSearch; 2637 } 2638 #endif 2639 2640 static 2641 DECLSPEC_NOINLINE 2642 int call_test(int (* func)(void)) 2643 { 2644 static int ret; 2645 static struct volatile_context before, after; 2646 static LPTOP_LEVEL_EXCEPTION_FILTER prev_unhandled_exception; 2647 #if defined(_X86_) && !defined(_PSEH3_H_) && !defined(_MSC_VER) 2648 static _SEH2Registration_t * prev_frame; 2649 _SEH2Registration_t passthrough_frame; 2650 #endif 2651 2652 prev_unhandled_exception = SetUnhandledExceptionFilter(&unhandled_exception); 2653 2654 #if defined(_X86_) && !defined(_PSEH3_H_) && !defined(_MSC_VER) 2655 prev_frame = (_SEH2Registration_t *)__readfsdword(0); 2656 passthrough_frame.SER_Prev = prev_frame; 2657 passthrough_frame.SER_Handler = passthrough_handler; 2658 __writefsdword(0, (unsigned long)&passthrough_frame); 2659 #endif 2660 2661 #if defined(__GNUC__) && defined(__i386__) 2662 __asm__ __volatile__ 2663 ( 2664 "mov %%esp, 0x00 + %c[before]\n" 2665 "mov %%ebp, 0x04 + %c[before]\n" 2666 "mov %%ebx, 0x08 + %c[before]\n" 2667 "mov %%esi, 0x0c + %c[before]\n" 2668 "mov %%edi, 0x10 + %c[before]\n" 2669 "call *%[test]\n" 2670 "mov %%esp, 0x00 + %c[after]\n" 2671 "mov %%ebp, 0x04 + %c[after]\n" 2672 "mov %%ebx, 0x08 + %c[after]\n" 2673 "mov %%esi, 0x0c + %c[after]\n" 2674 "mov %%edi, 0x10 + %c[after]\n" 2675 "push %[after]\n" 2676 "push %[before]\n" 2677 "push %[ret]\n" 2678 "call %c[sanity_check]\n" 2679 "pop %%ecx\n" 2680 "pop %%ecx\n" 2681 "pop %%ecx\n" : 2682 [ret] "=a" (ret) : 2683 [test] "r" (func), [before] "i" (&before), [after] "i" (&after), [sanity_check] "i" (&sanity_check) : 2684 "ebx", "ecx", "edx", "esi", "edi", "flags", "memory" 2685 ); 2686 #else 2687 ret = func(); 2688 #endif 2689 2690 #if defined(_X86_) && !defined(_PSEH3_H_) && !defined(_MSC_VER) 2691 if((_SEH2Registration_t *)__readfsdword(0) != &passthrough_frame || passthrough_frame.SER_Prev != prev_frame) 2692 { 2693 trace("exception registration list corrupted\n"); 2694 ret = 0; 2695 } 2696 2697 __writefsdword(0, (unsigned long)prev_frame); 2698 #endif 2699 2700 SetUnhandledExceptionFilter(prev_unhandled_exception); 2701 return ret; 2702 } 2703 2704 DEFINE_TEST(test_PSEH3_bug) 2705 { 2706 volatile int count = 0; 2707 int dummy = 0; 2708 2709 _SEH2_TRY 2710 { 2711 if (count++ == 0) 2712 { 2713 *(volatile int*)0x12345678 = 0x12345678; 2714 } 2715 } 2716 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2717 { 2718 dummy = 0; 2719 } 2720 _SEH2_END; 2721 2722 (void)dummy; 2723 return (count == 1); 2724 } 2725 2726 void 2727 use_lots_of_stack(void) 2728 { 2729 int i; 2730 volatile int arr[512]; 2731 for (i = 0; i < 512; i++) 2732 arr[i] = 123; 2733 (void)arr; 2734 } 2735 2736 DEFINE_TEST(test_PSEH3_bug2) 2737 { 2738 unsigned long status = 0; 2739 _SEH2_TRY 2740 { 2741 *(volatile int*)0x12345678 = 0x12345678; 2742 } 2743 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 2744 { 2745 use_lots_of_stack(); 2746 status = _SEH2_GetExceptionCode(); 2747 } 2748 _SEH2_END; 2749 2750 return (status == STATUS_ACCESS_VIOLATION); 2751 } 2752 2753 #define USE_TEST_NAME_(NAME_) # NAME_ 2754 #define USE_TEST_NAME(NAME_) USE_TEST_NAME_(NAME_) 2755 #define USE_TEST(NAME_) { USE_TEST_NAME(NAME_), NAME_ } 2756 2757 struct subtest 2758 { 2759 const char * name; 2760 int (* func)(void); 2761 }; 2762 2763 START_TEST(pseh) 2764 { 2765 const struct subtest testsuite[] = 2766 { 2767 USE_TEST(test_empty_1), 2768 USE_TEST(test_empty_2), 2769 USE_TEST(test_empty_3), 2770 USE_TEST(test_empty_4), 2771 USE_TEST(test_empty_5), 2772 USE_TEST(test_empty_6), 2773 USE_TEST(test_empty_7), 2774 USE_TEST(test_empty_8), 2775 2776 USE_TEST(test_execute_handler_1), 2777 USE_TEST(test_continue_execution_1), 2778 USE_TEST(test_continue_search_1), 2779 USE_TEST(test_execute_handler_2), 2780 USE_TEST(test_continue_execution_2), 2781 2782 USE_TEST(test_execute_handler_3), 2783 USE_TEST(test_continue_execution_3), 2784 USE_TEST(test_continue_search_2), 2785 USE_TEST(test_execute_handler_4), 2786 USE_TEST(test_continue_execution_4), 2787 2788 USE_TEST(test_execute_handler_5), 2789 USE_TEST(test_continue_execution_5), 2790 USE_TEST(test_continue_search_3), 2791 USE_TEST(test_execute_handler_6), 2792 USE_TEST(test_continue_execution_6), 2793 2794 USE_TEST(test_execute_handler_7), 2795 USE_TEST(test_continue_execution_7), 2796 USE_TEST(test_continue_search_4), 2797 USE_TEST(test_execute_handler_8), 2798 USE_TEST(test_continue_execution_8), 2799 2800 USE_TEST(test_execute_handler_9), 2801 USE_TEST(test_continue_execution_9), 2802 USE_TEST(test_continue_search_5), 2803 USE_TEST(test_execute_handler_10), 2804 USE_TEST(test_continue_execution_10), 2805 2806 USE_TEST(test_execute_handler_11), 2807 USE_TEST(test_continue_execution_11), 2808 USE_TEST(test_continue_search_6), 2809 USE_TEST(test_execute_handler_12), 2810 USE_TEST(test_continue_execution_12), 2811 2812 USE_TEST(test_leave_1), 2813 USE_TEST(test_leave_2), 2814 USE_TEST(test_leave_3), 2815 USE_TEST(test_leave_4), 2816 USE_TEST(test_leave_5), 2817 USE_TEST(test_leave_6), 2818 2819 USE_TEST(test_yield_1), 2820 USE_TEST(test_yield_2), 2821 USE_TEST(test_yield_3), 2822 USE_TEST(test_yield_4), 2823 USE_TEST(test_yield_5), 2824 USE_TEST(test_yield_6), 2825 2826 USE_TEST(test_finally_1), 2827 USE_TEST(test_finally_2), 2828 USE_TEST(test_finally_3), 2829 USE_TEST(test_finally_4), 2830 USE_TEST(test_finally_5), 2831 USE_TEST(test_finally_6), 2832 USE_TEST(test_finally_7), 2833 USE_TEST(test_finally_8), 2834 USE_TEST(test_finally_9), 2835 USE_TEST(test_finally_10), 2836 USE_TEST(test_finally_11), 2837 USE_TEST(test_finally_12), 2838 USE_TEST(test_finally_13), 2839 USE_TEST(test_finally_14), 2840 2841 USE_TEST(test_xpointers_1), 2842 USE_TEST(test_xpointers_2), 2843 USE_TEST(test_xpointers_3), 2844 USE_TEST(test_xpointers_4), 2845 USE_TEST(test_xpointers_5), 2846 USE_TEST(test_xpointers_6), 2847 USE_TEST(test_xpointers_7), 2848 USE_TEST(test_xpointers_8), 2849 USE_TEST(test_xpointers_9), 2850 USE_TEST(test_xpointers_10), 2851 USE_TEST(test_xpointers_11), 2852 USE_TEST(test_xpointers_12), 2853 USE_TEST(test_xpointers_13), 2854 USE_TEST(test_xpointers_14), 2855 USE_TEST(test_xpointers_15), 2856 USE_TEST(test_xpointers_16), 2857 2858 USE_TEST(test_xcode_1), 2859 USE_TEST(test_xcode_2), 2860 USE_TEST(test_xcode_3), 2861 2862 USE_TEST(test_abnorm_1), 2863 USE_TEST(test_abnorm_2), 2864 USE_TEST(test_abnorm_3), 2865 USE_TEST(test_abnorm_4), 2866 USE_TEST(test_abnorm_5), 2867 USE_TEST(test_abnorm_6), 2868 USE_TEST(test_abnorm_7), 2869 USE_TEST(test_abnorm_8), 2870 2871 USE_TEST(test_nested_locals_1), 2872 USE_TEST(test_nested_locals_2), 2873 USE_TEST(test_nested_locals_3), 2874 2875 USE_TEST(test_bug_4004), 2876 USE_TEST(test_bug_4663), 2877 2878 USE_TEST(test_unvolatile), 2879 USE_TEST(test_unvolatile_2), 2880 #ifndef __cplusplus 2881 USE_TEST(test_unvolatile_3), 2882 #endif 2883 USE_TEST(test_unvolatile_4), 2884 USE_TEST(test_finally_goto), 2885 USE_TEST(test_nested_exception), 2886 USE_TEST(test_PSEH3_bug), 2887 USE_TEST(test_PSEH3_bug2), 2888 }; 2889 2890 size_t i; 2891 2892 for(i = 0; i < sizeof(testsuite) / sizeof(testsuite[0]); ++ i) 2893 ok(call_test(testsuite[i].func), "%s failed\n", testsuite[i].name); 2894 } 2895 2896 /* EOF */ 2897