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