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