1/**************************************************************************** 2 * * 3 * GNAT COMPILER COMPONENTS * 4 * * 5 * R A I S E - G C C * 6 * * 7 * C Implementation File * 8 * * 9 * Copyright (C) 1992-2014, Free Software Foundation, Inc. * 10 * * 11 * GNAT is free software; you can redistribute it and/or modify it under * 12 * terms of the GNU General Public License as published by the Free Soft- * 13 * ware Foundation; either version 3, or (at your option) any later ver- * 14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- * 15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * 16 * or FITNESS FOR A PARTICULAR PURPOSE. * 17 * * 18 * As a special exception under Section 7 of GPL version 3, you are granted * 19 * additional permissions described in the GCC Runtime Library Exception, * 20 * version 3.1, as published by the Free Software Foundation. * 21 * * 22 * You should have received a copy of the GNU General Public License and * 23 * a copy of the GCC Runtime Library Exception along with this program; * 24 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see * 25 * <http://www.gnu.org/licenses/>. * 26 * * 27 * GNAT was originally developed by the GNAT team at New York University. * 28 * Extensive contributions were provided by Ada Core Technologies Inc. * 29 * * 30 ****************************************************************************/ 31 32/* Code related to the integration of the GCC mechanism for exception 33 handling. */ 34 35#ifndef IN_RTS 36#error "RTS unit only" 37#endif 38 39#include "tconfig.h" 40#include "tsystem.h" 41 42#include <stdarg.h> 43typedef char bool; 44# define true 1 45# define false 0 46 47#include "raise.h" 48 49#ifdef __APPLE__ 50/* On MacOS X, versions older than 10.5 don't export _Unwind_GetIPInfo. */ 51#undef HAVE_GETIPINFO 52#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 53#define HAVE_GETIPINFO 1 54#endif 55#endif 56 57#if defined (__hpux__) && defined (USE_LIBUNWIND_EXCEPTIONS) 58/* HP-UX B.11.31 ia64 libunwind doesn't have _Unwind_GetIPInfo. */ 59#undef HAVE_GETIPINFO 60#define _UA_END_OF_STACK 0 61#endif 62 63/* The names of a couple of "standard" routines for unwinding/propagation 64 actually vary depending on the underlying GCC scheme for exception handling 65 (SJLJ or DWARF). We need a consistently named interface to import from 66 a-except, so wrappers are defined here. */ 67 68#include "unwind.h" 69 70typedef struct _Unwind_Context _Unwind_Context; 71typedef struct _Unwind_Exception _Unwind_Exception; 72 73_Unwind_Reason_Code 74__gnat_Unwind_RaiseException (_Unwind_Exception *); 75 76_Unwind_Reason_Code 77__gnat_Unwind_ForcedUnwind (_Unwind_Exception *, void *, void *); 78 79extern struct Exception_Occurrence *__gnat_setup_current_excep 80 (_Unwind_Exception *); 81extern void __gnat_unhandled_except_handler (_Unwind_Exception *); 82 83#include "unwind-pe.h" 84 85/* The known and handled exception classes. */ 86 87#ifdef __ARM_EABI_UNWINDER__ 88#define CXX_EXCEPTION_CLASS "GNUCC++" 89#define GNAT_EXCEPTION_CLASS "GNU-Ada" 90#else 91#define CXX_EXCEPTION_CLASS 0x474e5543432b2b00ULL 92#define GNAT_EXCEPTION_CLASS 0x474e552d41646100ULL 93#endif 94 95/* Structure of a C++ exception, represented as a C structure... See 96 unwind-cxx.h for the full definition. */ 97 98struct __cxa_exception 99{ 100 void *exceptionType; 101 void (*exceptionDestructor)(void *); 102 103 void (*unexpectedHandler)(); 104 void (*terminateHandler)(); 105 106 struct __cxa_exception *nextException; 107 108 int handlerCount; 109 110#ifdef __ARM_EABI_UNWINDER__ 111 struct __cxa_exception* nextPropagatingException; 112 113 int propagationCount; 114#else 115 int handlerSwitchValue; 116 const unsigned char *actionRecord; 117 const unsigned char *languageSpecificData; 118 _Unwind_Ptr catchTemp; 119 void *adjustedPtr; 120#endif 121 122 _Unwind_Exception unwindHeader; 123}; 124 125/* -------------------------------------------------------------- 126 -- The DB stuff below is there for debugging purposes only. -- 127 -------------------------------------------------------------- */ 128 129#ifndef inhibit_libc 130 131#define DB_PHASES 0x1 132#define DB_CSITE 0x2 133#define DB_ACTIONS 0x4 134#define DB_REGIONS 0x8 135 136#define DB_ERR 0x1000 137 138/* The "action" stuff below is also there for debugging purposes only. */ 139 140typedef struct 141{ 142 _Unwind_Action phase; 143 const char * description; 144} phase_descriptor; 145 146static const phase_descriptor phase_descriptors[] 147 = {{ _UA_SEARCH_PHASE, "SEARCH_PHASE" }, 148 { _UA_CLEANUP_PHASE, "CLEANUP_PHASE" }, 149 { _UA_HANDLER_FRAME, "HANDLER_FRAME" }, 150 { _UA_FORCE_UNWIND, "FORCE_UNWIND" }, 151 { -1, 0}}; 152 153static int 154db_accepted_codes (void) 155{ 156 static int accepted_codes = -1; 157 158 if (accepted_codes == -1) 159 { 160 char * db_env = (char *) getenv ("EH_DEBUG"); 161 162 accepted_codes = db_env ? (atoi (db_env) | DB_ERR) : 0; 163 /* Arranged for ERR stuff to always be visible when the variable 164 is defined. One may just set the variable to 0 to see the ERR 165 stuff only. */ 166 } 167 168 return accepted_codes; 169} 170 171#define DB_INDENT_INCREASE 0x01 172#define DB_INDENT_DECREASE 0x02 173#define DB_INDENT_OUTPUT 0x04 174#define DB_INDENT_NEWLINE 0x08 175#define DB_INDENT_RESET 0x10 176 177#define DB_INDENT_UNIT 8 178 179static void 180db_indent (int requests) 181{ 182 static int current_indentation_level = 0; 183 184 if (requests & DB_INDENT_RESET) 185 current_indentation_level = 0; 186 187 if (requests & DB_INDENT_INCREASE) 188 current_indentation_level ++; 189 190 if (requests & DB_INDENT_DECREASE) 191 current_indentation_level --; 192 193 if (requests & DB_INDENT_NEWLINE) 194 fprintf (stderr, "\n"); 195 196 if (requests & DB_INDENT_OUTPUT) 197 fprintf (stderr, "%*s", current_indentation_level * DB_INDENT_UNIT, " "); 198} 199 200static void ATTRIBUTE_PRINTF_2 201db (int db_code, char * msg_format, ...) 202{ 203 if (db_accepted_codes () & db_code) 204 { 205 va_list msg_args; 206 207 db_indent (DB_INDENT_OUTPUT); 208 209 va_start (msg_args, msg_format); 210 vfprintf (stderr, msg_format, msg_args); 211 va_end (msg_args); 212 } 213} 214 215static void 216db_phases (int phases) 217{ 218 const phase_descriptor *a = phase_descriptors; 219 220 if (! (db_accepted_codes () & DB_PHASES)) 221 return; 222 223 db (DB_PHASES, "\n"); 224 225 for (; a->description != 0; a++) 226 if (phases & a->phase) 227 db (DB_PHASES, "%s ", a->description); 228 229 db (DB_PHASES, " :\n"); 230} 231#else /* !inhibit_libc */ 232#define db_phases(X) 233#define db_indent(X) 234#define db(X, ...) 235#endif /* !inhibit_libc */ 236 237/* --------------------------------------------------------------- 238 -- Now come a set of useful structures and helper routines. -- 239 --------------------------------------------------------------- */ 240 241/* There are three major runtime tables involved, generated by the 242 GCC back-end. Contents slightly vary depending on the underlying 243 implementation scheme (dwarf zero cost / sjlj). 244 245 ======================================= 246 * Tables for the dwarf zero cost case * 247 ======================================= 248 249 They are fully documented in: 250 http://sourcery.mentor.com/public/cxx-abi/exceptions.pdf 251 Here is a shorter presentation, with some specific comments for Ada. 252 253 call_site [] 254 ------------------------------------------------------------------- 255 * region-start | region-length | landing-pad | first-action-index * 256 ------------------------------------------------------------------- 257 258 Identify possible actions to be taken and where to resume control 259 for that when an exception propagates through a pc inside the region 260 delimited by start and length. 261 262 A null landing-pad indicates that nothing is to be done. 263 264 Otherwise, first-action-index provides an entry into the action[] 265 table which heads a list of possible actions to be taken (see below). 266 267 If it is determined that indeed an action should be taken, that 268 is, if one action filter matches the exception being propagated, 269 then control should be transferred to landing-pad. 270 271 A null first-action-index indicates that there are only cleanups 272 to run there. 273 274 action [] 275 ------------------------------- 276 * action-filter | next-action * 277 ------------------------------- 278 279 This table contains lists (called action chains) of possible actions 280 associated with call-site entries described in the call-site [] table. 281 There is at most one action list per call-site entry. It is SLEB128 282 encoded. 283 284 A null action-filter indicates a cleanup. 285 286 Non null action-filters provide an index into the ttypes [] table 287 (see below), from which information may be retrieved to check if it 288 matches the exception being propagated. 289 290 * action-filter > 0: 291 means there is a regular handler to be run The value is also passed 292 to the landing pad to dispatch the exception. 293 294 * action-filter < 0: 295 means there is a some "exception_specification" data to retrieve, 296 which is only relevant for C++ and should never show up for Ada. 297 (Exception specification specifies which exceptions can be thrown 298 by a function. Such filter is emitted around the body of C++ 299 functions defined like: 300 void foo ([...]) throw (A, B) { [...] } 301 These can be viewed as negativ filter: the landing pad is branched 302 to for exceptions that doesn't match the filter and usually aborts 303 the program). 304 305 * next-action 306 points to the next entry in the list using a relative byte offset. 0 307 indicates there is no other entry. 308 309 ttypes [] 310 --------------- 311 * ttype-value * 312 --------------- 313 314 This table is an array of addresses. 315 316 A null value indicates a catch-all handler. (Not used by Ada) 317 318 Non null values are used to match the exception being propagated: 319 In C++ this is a pointer to some rtti data, while in Ada this is an 320 exception id (with a fake id for others). 321 322 For C++, this table is actually also used to store "exception 323 specification" data. The differentiation between the two kinds 324 of entries is made by the sign of the associated action filter, 325 which translates into positive or negative offsets from the 326 so called base of the table: 327 328 Exception Specification data is stored at positive offsets from 329 the ttypes table base, which Exception Type data is stored at 330 negative offsets: 331 332 --------------------------------------------------------------------------- 333 334 Here is a quick summary of the tables organization: 335 336 +-- Unwind_Context (pc, ...) 337 | 338 |(pc) 339 | 340 | CALL-SITE[] 341 | 342 | +=============================================================+ 343 | | region-start + length | landing-pad | first-action-index | 344 | +=============================================================+ 345 +-> | pc range 0 => no-action 0 => cleanups only | 346 | !0 => jump @ N --+ | 347 +====================================================== | ====+ 348 | 349 | 350 ACTION [] | 351 | 352 +==========================================================+ | 353 | action-filter | next-action | | 354 +==========================================================+ | 355 | 0 => cleanup | | 356 | >0 => ttype index for handler ------+ 0 => end of chain | <-+ 357 | <0 => ttype index for spec data | | 358 +==================================== | ===================+ 359 | 360 | 361 TTYPES [] | 362 | Offset negated from 363 +=====================+ | the actual base. 364 | ttype-value | | 365 +============+=====================+ | 366 | | ... | | 367 | ... | exception id | <---+ 368 | | ... | 369 | handlers +---------------------+ 370 | | ... | 371 | ... | ... | 372 | | ... | 373 +============+=====================+ <<------ Table base 374 | ... | ... | 375 | specs | ... | (should not see negative filter 376 | ... | ... | values for Ada). 377 +============+=====================+ 378 379 380 ============================ 381 * Tables for the sjlj case * 382 ============================ 383 384 So called "function contexts" are pushed on a context stack by calls to 385 _Unwind_SjLj_Register on function entry, and popped off at exit points by 386 calls to _Unwind_SjLj_Unregister. The current call_site for a function is 387 updated in the function context as the function's code runs along. 388 389 The generic unwinding engine in _Unwind_RaiseException walks the function 390 context stack and not the actual call chain. 391 392 The ACTION and TTYPES tables remain unchanged, which allows to search them 393 during the propagation phase to determine whether or not the propagated 394 exception is handled somewhere. When it is, we only "jump" up once directly 395 to the context where the handler will be found. Besides, this allows "break 396 exception unhandled" to work also 397 398 The CALL-SITE table is setup differently, though: the pc attached to the 399 unwind context is a direct index into the table, so the entries in this 400 table do not hold region bounds any more. 401 402 A special index (-1) is used to indicate that no action is possibly 403 connected with the context at hand, so null landing pads cannot appear 404 in the table. 405 406 Additionally, landing pad values in the table do not represent code address 407 to jump at, but so called "dispatch" indices used by a common landing pad 408 for the function to switch to the appropriate post-landing-pad. 409 410 +-- Unwind_Context (pc, ...) 411 | 412 | pc = call-site index 413 | 0 => terminate (should not see this for Ada) 414 | -1 => no-action 415 | 416 | CALL-SITE[] 417 | 418 | +=====================================+ 419 | | landing-pad | first-action-index | 420 | +=====================================+ 421 +-> | 0 => cleanups only | 422 | dispatch index N | 423 +=====================================+ 424 425 426 =================================== 427 * Basic organization of this unit * 428 =================================== 429 430 The major point of this unit is to provide an exception propagation 431 personality routine for Ada. This is __gnat_personality_v0. 432 433 It is provided with a pointer to the propagated exception, an unwind 434 context describing a location the propagation is going through, and a 435 couple of other arguments including a description of the current 436 propagation phase. 437 438 It shall return to the generic propagation engine what is to be performed 439 next, after possible context adjustments, depending on what it finds in the 440 traversed context (a handler for the exception, a cleanup, nothing, ...), 441 and on the propagation phase. 442 443 A number of structures and subroutines are used for this purpose, as 444 sketched below: 445 446 o region_descriptor: General data associated with the context (base pc, 447 call-site table, action table, ttypes table, ...) 448 449 o action_descriptor: Data describing the action to be taken for the 450 propagated exception in the provided context (kind of action: nothing, 451 handler, cleanup; pointer to the action table entry, ...). 452 453 raise 454 | 455 ... (a-except.adb) 456 | 457 Propagate_Exception (a-exexpr.adb) 458 | 459 | 460 _Unwind_RaiseException (libgcc) 461 | 462 | (Ada frame) 463 | 464 +--> __gnat_personality_v0 (context, exception) 465 | 466 +--> get_region_description_for (context) 467 | 468 +--> get_action_description_for (ip, exception, region) 469 | | 470 | +--> get_call_site_action_for (context, region) 471 | (one version for each underlying scheme) 472 | 473 +--> setup_to_install (context) 474 475 This unit is inspired from the C++ version found in eh_personality.cc, 476 part of libstdc++-v3. 477 478*/ 479 480 481/* This is an incomplete "proxy" of the structure of exception objects as 482 built by the GNAT runtime library. Accesses to other fields than the common 483 header are performed through subprogram calls to alleviate the need of an 484 exact counterpart here and potential alignment/size issues for the common 485 header. See a-exexpr.adb. */ 486 487typedef struct 488{ 489 _Unwind_Exception common; 490 /* ABI header, maximally aligned. */ 491} _GNAT_Exception; 492 493/* The two constants below are specific ttype identifiers for special 494 exception ids. Their type should match what a-exexpr exports. */ 495 496extern const int __gnat_others_value; 497#define GNAT_OTHERS ((_Unwind_Ptr) &__gnat_others_value) 498 499extern const int __gnat_all_others_value; 500#define GNAT_ALL_OTHERS ((_Unwind_Ptr) &__gnat_all_others_value) 501 502extern const int __gnat_unhandled_others_value; 503#define GNAT_UNHANDLED_OTHERS ((_Unwind_Ptr) &__gnat_unhandled_others_value) 504 505/* Describe the useful region data associated with an unwind context. */ 506 507typedef struct 508{ 509 /* The base pc of the region. */ 510 _Unwind_Ptr base; 511 512 /* Pointer to the Language Specific Data for the region. */ 513 _Unwind_Ptr lsda; 514 515 /* Call-Site data associated with this region. */ 516 unsigned char call_site_encoding; 517 const unsigned char *call_site_table; 518 519 /* The base to which are relative landing pad offsets inside the call-site 520 entries . */ 521 _Unwind_Ptr lp_base; 522 523 /* Action-Table associated with this region. */ 524 const unsigned char *action_table; 525 526 /* Ttype data associated with this region. */ 527 unsigned char ttype_encoding; 528 const unsigned char *ttype_table; 529 _Unwind_Ptr ttype_base; 530 531} region_descriptor; 532 533/* Extract and adjust the IP (instruction pointer) from an exception 534 context. */ 535 536static _Unwind_Ptr 537get_ip_from_context (_Unwind_Context *uw_context) 538{ 539 int ip_before_insn = 0; 540#ifdef HAVE_GETIPINFO 541 _Unwind_Ptr ip = _Unwind_GetIPInfo (uw_context, &ip_before_insn); 542#else 543 _Unwind_Ptr ip = _Unwind_GetIP (uw_context); 544#endif 545 /* Subtract 1 if necessary because GetIPInfo yields a call return address 546 in this case, while we are interested in information for the call point. 547 This does not always yield the exact call instruction address but always 548 brings the IP back within the corresponding region. */ 549 if (!ip_before_insn) 550 ip--; 551 552 return ip; 553} 554 555static void 556db_region_for (region_descriptor *region, _Unwind_Ptr ip) 557{ 558#ifndef inhibit_libc 559 if (! (db_accepted_codes () & DB_REGIONS)) 560 return; 561 562 db (DB_REGIONS, "For ip @ %p => ", (void *)ip); 563 564 if (region->lsda) 565 db (DB_REGIONS, "lsda @ %p", (void *)region->lsda); 566 else 567 db (DB_REGIONS, "no lsda"); 568 569 db (DB_REGIONS, "\n"); 570#endif 571} 572 573/* Retrieve the ttype entry associated with FILTER in the REGION's 574 ttype table. */ 575 576static _Unwind_Ptr 577get_ttype_entry_for (region_descriptor *region, long filter) 578{ 579 _Unwind_Ptr ttype_entry; 580 581 filter *= size_of_encoded_value (region->ttype_encoding); 582 read_encoded_value_with_base 583 (region->ttype_encoding, region->ttype_base, 584 region->ttype_table - filter, &ttype_entry); 585 586 return ttype_entry; 587} 588 589/* Fill out the REGION descriptor for the provided UW_CONTEXT. */ 590 591static void 592get_region_description_for (_Unwind_Context *uw_context, 593 region_descriptor *region) 594{ 595 const unsigned char * p; 596 _uleb128_t tmp; 597 unsigned char lpbase_encoding; 598 599 /* Get the base address of the lsda information. If the provided context 600 is null or if there is no associated language specific data, there's 601 nothing we can/should do. */ 602 region->lsda 603 = (_Unwind_Ptr) (uw_context 604 ? _Unwind_GetLanguageSpecificData (uw_context) : 0); 605 606 if (! region->lsda) 607 return; 608 609 /* Parse the lsda and fill the region descriptor. */ 610 p = (const unsigned char *)region->lsda; 611 612 region->base = _Unwind_GetRegionStart (uw_context); 613 614 /* Find @LPStart, the base to which landing pad offsets are relative. */ 615 lpbase_encoding = *p++; 616 if (lpbase_encoding != DW_EH_PE_omit) 617 p = read_encoded_value 618 (uw_context, lpbase_encoding, p, ®ion->lp_base); 619 else 620 region->lp_base = region->base; 621 622 /* Find @TType, the base of the handler and exception spec type data. */ 623 region->ttype_encoding = *p++; 624 if (region->ttype_encoding != DW_EH_PE_omit) 625 { 626 p = read_uleb128 (p, &tmp); 627 region->ttype_table = p + tmp; 628 } 629 else 630 region->ttype_table = 0; 631 632 region->ttype_base 633 = base_of_encoded_value (region->ttype_encoding, uw_context); 634 635 /* Get the encoding and length of the call-site table; the action table 636 immediately follows. */ 637 region->call_site_encoding = *p++; 638 region->call_site_table = read_uleb128 (p, &tmp); 639 640 region->action_table = region->call_site_table + tmp; 641} 642 643 644/* Describe an action to be taken when propagating an exception up to 645 some context. */ 646 647enum action_kind 648{ 649 /* Found some call site base data, but need to analyze further 650 before being able to decide. */ 651 unknown, 652 653 /* There is nothing relevant in the context at hand. */ 654 nothing, 655 656 /* There are only cleanups to run in this context. */ 657 cleanup, 658 659 /* There is a handler for the exception in this context. */ 660 handler, 661 662 /* There is a handler for the exception, but it is only for catching 663 unhandled exceptions. */ 664 unhandler 665}; 666 667/* filter value for cleanup actions. */ 668static const int cleanup_filter = 0; 669 670typedef struct 671{ 672 /* The kind of action to be taken. */ 673 enum action_kind kind; 674 675 /* A pointer to the action record entry. */ 676 const unsigned char *table_entry; 677 678 /* Where we should jump to actually take an action (trigger a cleanup or an 679 exception handler). */ 680 _Unwind_Ptr landing_pad; 681 682 /* If we have a handler matching our exception, these are the filter to 683 trigger it and the corresponding id. */ 684 _Unwind_Sword ttype_filter; 685 686} action_descriptor; 687 688static void 689db_action_for (action_descriptor *action, _Unwind_Ptr ip) 690{ 691#ifndef inhibit_libc 692 db (DB_ACTIONS, "For ip @ %p => ", (void *)ip); 693 694 switch (action->kind) 695 { 696 case unknown: 697 db (DB_ACTIONS, "lpad @ %p, record @ %p\n", 698 (void *) action->landing_pad, action->table_entry); 699 break; 700 701 case nothing: 702 db (DB_ACTIONS, "Nothing\n"); 703 break; 704 705 case cleanup: 706 db (DB_ACTIONS, "Cleanup\n"); 707 break; 708 709 case handler: 710 db (DB_ACTIONS, "Handler, filter = %d\n", (int) action->ttype_filter); 711 break; 712 713 default: 714 db (DB_ACTIONS, "Err? Unexpected action kind !\n"); 715 break; 716 } 717#endif 718} 719 720/* Search the call_site_table of REGION for an entry appropriate for the 721 UW_CONTEXT's IP. If one is found, store the associated landing_pad 722 and action_table entry, and set the ACTION kind to unknown for further 723 analysis. Otherwise, set the ACTION kind to nothing. 724 725 There are two variants of this routine, depending on the underlying 726 mechanism (DWARF/SJLJ), which account for differences in the tables. */ 727 728#ifdef __USING_SJLJ_EXCEPTIONS__ 729 730#define __builtin_eh_return_data_regno(x) x 731 732static void 733get_call_site_action_for (_Unwind_Ptr call_site, 734 region_descriptor *region, 735 action_descriptor *action) 736{ 737 /* call_site is a direct index into the call-site table, with two special 738 values : -1 for no-action and 0 for "terminate". The latter should never 739 show up for Ada. To test for the former, beware that _Unwind_Ptr might 740 be unsigned. */ 741 742 if ((int)call_site < 0) 743 { 744 action->kind = nothing; 745 } 746 else if (call_site == 0) 747 { 748 db (DB_ERR, "========> Err, null call_site for Ada/sjlj\n"); 749 action->kind = nothing; 750 } 751 else 752 { 753 _uleb128_t cs_lp, cs_action; 754 const unsigned char *p; 755 756 /* Let the caller know there may be an action to take, but let it 757 determine the kind. */ 758 action->kind = unknown; 759 760 /* We have a direct index into the call-site table, but this table is 761 made of leb128 values, the encoding length of which is variable. We 762 can't merely compute an offset from the index, then, but have to read 763 all the entries before the one of interest. */ 764 p = region->call_site_table; 765 do 766 { 767 p = read_uleb128 (p, &cs_lp); 768 p = read_uleb128 (p, &cs_action); 769 } 770 while (--call_site); 771 772 action->landing_pad = cs_lp + 1; 773 774 if (cs_action) 775 action->table_entry = region->action_table + cs_action - 1; 776 else 777 action->table_entry = 0; 778 } 779} 780 781#else /* !__USING_SJLJ_EXCEPTIONS__ */ 782 783static void 784get_call_site_action_for (_Unwind_Ptr ip, 785 region_descriptor *region, 786 action_descriptor *action) 787{ 788 const unsigned char *p = region->call_site_table; 789 790 /* Unless we are able to determine otherwise... */ 791 action->kind = nothing; 792 793 db (DB_CSITE, "\n"); 794 795 while (p < region->action_table) 796 { 797 _Unwind_Ptr cs_start, cs_len, cs_lp; 798 _uleb128_t cs_action; 799 800 /* Note that all call-site encodings are "absolute" displacements. */ 801 p = read_encoded_value (0, region->call_site_encoding, p, &cs_start); 802 p = read_encoded_value (0, region->call_site_encoding, p, &cs_len); 803 p = read_encoded_value (0, region->call_site_encoding, p, &cs_lp); 804 p = read_uleb128 (p, &cs_action); 805 806 db (DB_CSITE, 807 "c_site @ %p (+%p), len = %p, lpad @ %p (+%p)\n", 808 (void *)region->base + cs_start, (void *)cs_start, (void *)cs_len, 809 (void *)region->lp_base + cs_lp, (void *)cs_lp); 810 811 /* The table is sorted, so if we've passed the IP, stop. */ 812 if (ip < region->base + cs_start) 813 break; 814 815 /* If we have a match, fill the ACTION fields accordingly. */ 816 else if (ip < region->base + cs_start + cs_len) 817 { 818 /* Let the caller know there may be an action to take, but let it 819 determine the kind. */ 820 action->kind = unknown; 821 822 if (cs_lp) 823 action->landing_pad = region->lp_base + cs_lp; 824 else 825 action->landing_pad = 0; 826 827 if (cs_action) 828 action->table_entry = region->action_table + cs_action - 1; 829 else 830 action->table_entry = 0; 831 832 db (DB_CSITE, "+++\n"); 833 return; 834 } 835 } 836 837 db (DB_CSITE, "---\n"); 838} 839 840#endif /* __USING_SJLJ_EXCEPTIONS__ */ 841 842/* With CHOICE an exception choice representing an "exception - when" 843 argument, and PROPAGATED_EXCEPTION a pointer to the currently propagated 844 occurrence, return true if the latter matches the former, that is, if 845 PROPAGATED_EXCEPTION is caught by the handling code controlled by CHOICE. 846 This takes care of the special Non_Ada_Error case on VMS. */ 847 848#define Is_Handled_By_Others __gnat_is_handled_by_others 849#define Language_For __gnat_language_for 850#define Foreign_Data_For __gnat_foreign_data_for 851#define EID_For __gnat_eid_for 852 853extern bool Is_Handled_By_Others (_Unwind_Ptr eid); 854extern char Language_For (_Unwind_Ptr eid); 855 856extern void *Foreign_Data_For (_Unwind_Ptr eid); 857 858extern Exception_Id EID_For (_GNAT_Exception * e); 859 860#define Foreign_Exception system__exceptions__foreign_exception 861extern struct Exception_Data Foreign_Exception; 862 863#ifdef VMS 864#define Non_Ada_Error system__aux_dec__non_ada_error 865extern struct Exception_Data Non_Ada_Error; 866#endif 867 868/* Return true iff the exception class of EXCEPT is EC. */ 869 870static int 871exception_class_eq (const _GNAT_Exception *except, _Unwind_Exception_Class ec) 872{ 873#ifdef __ARM_EABI_UNWINDER__ 874 return memcmp (except->common.exception_class, ec, 8) == 0; 875#else 876 return except->common.exception_class == ec; 877#endif 878} 879 880/* Return how CHOICE matches PROPAGATED_EXCEPTION. */ 881 882static enum action_kind 883is_handled_by (_Unwind_Ptr choice, _GNAT_Exception *propagated_exception) 884{ 885 /* All others choice match everything. */ 886 if (choice == GNAT_ALL_OTHERS) 887 return handler; 888 889 /* GNAT exception occurrence. */ 890 if (exception_class_eq (propagated_exception, GNAT_EXCEPTION_CLASS)) 891 { 892 /* Pointer to the GNAT exception data corresponding to the propagated 893 occurrence. */ 894 _Unwind_Ptr E = (_Unwind_Ptr) EID_For (propagated_exception); 895 896 if (choice == GNAT_UNHANDLED_OTHERS) 897 return unhandler; 898 899 E = (_Unwind_Ptr) EID_For (propagated_exception); 900 901 /* Base matching rules: An exception data (id) matches itself, "when 902 all_others" matches anything and "when others" matches anything 903 unless explicitly stated otherwise in the propagated occurrence. */ 904 if (choice == E || (choice == GNAT_OTHERS && Is_Handled_By_Others (E))) 905 return handler; 906 907#ifdef VMS 908 /* In addition, on OpenVMS, Non_Ada_Error matches VMS exceptions, and we 909 may have different exception data pointers that should match for the 910 same condition code, if both an export and an import have been 911 registered. The import code for both the choice and the propagated 912 occurrence are expected to have been masked off regarding severity 913 bits already (at registration time for the former and from within the 914 low level exception vector for the latter). */ 915 if ((Language_For (E) == 'V' 916 && choice != GNAT_OTHERS 917 && ((Language_For (choice) == 'V' 918 && Foreign_Data_For (choice) != 0 919 && Foreign_Data_For (choice) == Foreign_Data_For (E)) 920 || choice == (_Unwind_Ptr)&Non_Ada_Error))) 921 return handler; 922#endif 923 924 /* Otherwise, it doesn't match an Ada choice. */ 925 return nothing; 926 } 927 928 /* All others and others choice match any foreign exception. */ 929 if (choice == GNAT_ALL_OTHERS 930 || choice == GNAT_OTHERS 931 || choice == (_Unwind_Ptr) &Foreign_Exception) 932 return handler; 933 934 /* C++ exception occurrences. */ 935 if (exception_class_eq (propagated_exception, CXX_EXCEPTION_CLASS) 936 && Language_For (choice) == 'C') 937 { 938 void *choice_typeinfo = Foreign_Data_For (choice); 939 void *except_typeinfo = 940 (((struct __cxa_exception *) 941 ((_Unwind_Exception *)propagated_exception + 1)) - 1) 942 ->exceptionType; 943 944 /* Typeinfo are directly compared, which might not be correct if they 945 aren't merged. ??? We should call the == operator if this module is 946 compiled in C++. */ 947 if (choice_typeinfo == except_typeinfo) 948 return handler; 949 } 950 951 return nothing; 952} 953 954/* Fill out the ACTION to be taken from propagating UW_EXCEPTION up to 955 UW_CONTEXT in REGION. */ 956 957static void 958get_action_description_for (_Unwind_Ptr ip, 959 _Unwind_Exception *uw_exception, 960 _Unwind_Action uw_phase, 961 region_descriptor *region, 962 action_descriptor *action) 963{ 964 _GNAT_Exception *gnat_exception = (_GNAT_Exception *) uw_exception; 965 966 /* Search the call site table first, which may get us a landing pad as well 967 as the head of an action record list. */ 968 get_call_site_action_for (ip, region, action); 969 db_action_for (action, ip); 970 971 /* If there is not even a call_site entry, we are done. */ 972 if (action->kind == nothing) 973 return; 974 975 /* Otherwise, check what we have at the place of the call site. */ 976 977 /* No landing pad => no cleanups or handlers. */ 978 if (action->landing_pad == 0) 979 { 980 action->kind = nothing; 981 return; 982 } 983 984 /* Landing pad + null table entry => only cleanups. */ 985 else if (action->table_entry == 0) 986 { 987 action->kind = cleanup; 988 action->ttype_filter = cleanup_filter; 989 /* The filter initialization is not strictly necessary, as cleanup-only 990 landing pads don't look at the filter value. It is there to ensure 991 we don't pass random values and so trigger potential confusion when 992 installing the context later on. */ 993 return; 994 } 995 996 /* Landing pad + Table entry => handlers + possible cleanups. */ 997 else 998 { 999 const unsigned char * p = action->table_entry; 1000 _sleb128_t ar_filter, ar_disp; 1001 1002 action->kind = nothing; 1003 1004 while (1) 1005 { 1006 p = read_sleb128 (p, &ar_filter); 1007 read_sleb128 (p, &ar_disp); 1008 /* Don't assign p here, as it will be incremented by ar_disp 1009 below. */ 1010 1011 /* Null filters are for cleanups. */ 1012 if (ar_filter == cleanup_filter) 1013 { 1014 action->kind = cleanup; 1015 action->ttype_filter = cleanup_filter; 1016 /* The filter initialization is required here, to ensure 1017 the target landing pad branches to the cleanup code if 1018 we happen not to find a matching handler. */ 1019 } 1020 1021 /* Positive filters are for regular handlers. */ 1022 else if (ar_filter > 0) 1023 { 1024 /* Do not catch an exception if the _UA_FORCE_UNWIND flag is 1025 passed (to follow the ABI). */ 1026 if (!(uw_phase & _UA_FORCE_UNWIND)) 1027 { 1028 enum action_kind act; 1029 1030 /* See if the filter we have is for an exception which 1031 matches the one we are propagating. */ 1032 _Unwind_Ptr choice = 1033 get_ttype_entry_for (region, ar_filter); 1034 1035 act = is_handled_by (choice, gnat_exception); 1036 if (act != nothing) 1037 { 1038 action->kind = act; 1039 action->ttype_filter = ar_filter; 1040 return; 1041 } 1042 } 1043 } 1044 1045 /* Negative filter values are for C++ exception specifications. 1046 Should not be there for Ada :/ */ 1047 else 1048 db (DB_ERR, "========> Err, filter < 0 for Ada/dwarf\n"); 1049 1050 if (ar_disp == 0) 1051 return; 1052 1053 p += ar_disp; 1054 } 1055 } 1056} 1057 1058/* Setup in UW_CONTEXT the eh return target IP and data registers, which will 1059 be restored with the others and retrieved by the landing pad once the jump 1060 occurred. */ 1061 1062static void 1063setup_to_install (_Unwind_Context *uw_context, 1064 _Unwind_Exception *uw_exception, 1065 _Unwind_Ptr uw_landing_pad, 1066 int uw_filter) 1067{ 1068 /* 1/ exception object pointer, which might be provided back to 1069 _Unwind_Resume (and thus to this personality routine) if we are jumping 1070 to a cleanup. */ 1071 _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (0), 1072 (_Unwind_Word)uw_exception); 1073 1074 /* 2/ handler switch value register, which will also be used by the target 1075 landing pad to decide what action it shall take. */ 1076 _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (1), 1077 (_Unwind_Word)uw_filter); 1078 1079 /* Setup the address we should jump at to reach the code where there is the 1080 "something" we found. */ 1081 _Unwind_SetIP (uw_context, uw_landing_pad); 1082} 1083 1084/* The following is defined from a-except.adb. Its purpose is to enable 1085 automatic backtraces upon exception raise, as provided through the 1086 GNAT.Traceback facilities. */ 1087extern void __gnat_notify_handled_exception (struct Exception_Occurrence *); 1088extern void __gnat_notify_unhandled_exception (struct Exception_Occurrence *); 1089 1090/* Below is the eh personality routine per se. We currently assume that only 1091 GNU-Ada exceptions are met. */ 1092 1093/* By default, the personality routine is public. */ 1094#define PERSONALITY_STORAGE 1095 1096#ifdef __USING_SJLJ_EXCEPTIONS__ 1097#define PERSONALITY_FUNCTION __gnat_personality_sj0 1098#elif defined (__SEH__) 1099#define PERSONALITY_FUNCTION __gnat_personality_imp 1100/* The public personality routine for seh is __gnat_personality_seh0, defined 1101 below using the SEH convention. This is a wrapper around the GNU routine, 1102 which is static. */ 1103#undef PERSONALITY_STORAGE 1104#define PERSONALITY_STORAGE static 1105#else 1106#define PERSONALITY_FUNCTION __gnat_personality_v0 1107#endif 1108 1109/* Code executed to continue unwinding. With the ARM unwinder, the 1110 personality routine must unwind one frame (per EHABI 7.3 4.). */ 1111 1112static _Unwind_Reason_Code 1113continue_unwind (struct _Unwind_Exception* ue_header ATTRIBUTE_UNUSED, 1114 struct _Unwind_Context* uw_context ATTRIBUTE_UNUSED) 1115{ 1116#ifdef __ARM_EABI_UNWINDER__ 1117 if (__gnu_unwind_frame (ue_header, uw_context) != _URC_OK) 1118 return _URC_FAILURE; 1119#endif 1120 return _URC_CONTINUE_UNWIND; 1121} 1122 1123/* Common code for the body of GNAT personality routine. This code is shared 1124 between all unwinders. */ 1125 1126static _Unwind_Reason_Code 1127personality_body (_Unwind_Action uw_phases, 1128 _Unwind_Exception *uw_exception, 1129 _Unwind_Context *uw_context) 1130{ 1131 region_descriptor region; 1132 action_descriptor action; 1133 _Unwind_Ptr ip; 1134 1135 /* Debug traces. */ 1136 db_indent (DB_INDENT_RESET); 1137 db_phases (uw_phases); 1138 db_indent (DB_INDENT_INCREASE); 1139 1140 /* Get the region description for the context we were provided with. This 1141 will tell us if there is some lsda, call_site, action and/or ttype data 1142 for the associated ip. */ 1143 get_region_description_for (uw_context, ®ion); 1144 1145 /* No LSDA => no handlers or cleanups => we shall unwind further up. */ 1146 if (! region.lsda) 1147 return continue_unwind (uw_exception, uw_context); 1148 1149 /* Get the instruction pointer. */ 1150 ip = get_ip_from_context (uw_context); 1151 db_region_for (®ion, ip); 1152 1153 /* Search the call-site and action-record tables for the action associated 1154 with this IP. */ 1155 get_action_description_for (ip, uw_exception, uw_phases, ®ion, &action); 1156 db_action_for (&action, ip); 1157 1158 /* Whatever the phase, if there is nothing relevant in this frame, 1159 unwinding should just go on. */ 1160 if (action.kind == nothing) 1161 return continue_unwind (uw_exception, uw_context); 1162 1163 /* If we found something in search phase, we should return a code indicating 1164 what to do next depending on what we found. If we only have cleanups 1165 around, we shall try to unwind further up to find a handler, otherwise, 1166 tell we have a handler, which will trigger the second phase. */ 1167 if (uw_phases & _UA_SEARCH_PHASE) 1168 { 1169 if (action.kind == cleanup) 1170 { 1171 return continue_unwind (uw_exception, uw_context); 1172 } 1173 else 1174 { 1175 struct Exception_Occurrence *excep; 1176 1177 /* Trigger the appropriate notification routines before the second 1178 phase starts, which ensures the stack is still intact. 1179 First, setup the Ada occurrence. */ 1180 excep = __gnat_setup_current_excep (uw_exception); 1181 if (action.kind == unhandler) 1182 __gnat_notify_unhandled_exception (excep); 1183 else 1184 __gnat_notify_handled_exception (excep); 1185 1186 return _URC_HANDLER_FOUND; 1187 } 1188 } 1189 1190 /* We found something in cleanup/handler phase, which might be the handler 1191 or a cleanup for a handled occurrence, or a cleanup for an unhandled 1192 occurrence (we are in a FORCED_UNWIND phase in this case). Install the 1193 context to get there. */ 1194 1195 setup_to_install 1196 (uw_context, uw_exception, action.landing_pad, action.ttype_filter); 1197 1198 /* Write current exception, so that it can be retrieved from Ada. It was 1199 already done during phase 1 (just above), but in between, one or several 1200 exceptions may have been raised (in cleanup handlers). */ 1201 __gnat_setup_current_excep (uw_exception); 1202 1203 return _URC_INSTALL_CONTEXT; 1204} 1205 1206#ifndef __ARM_EABI_UNWINDER__ 1207/* Major tweak for ia64-vms : the CHF propagation phase calls this personality 1208 routine with sigargs/mechargs arguments and has very specific expectations 1209 on possible return values. 1210 1211 We handle this with a number of specific tricks: 1212 1213 1. We tweak the personality routine prototype to have the "version" and 1214 "phases" two first arguments be void * instead of int and _Unwind_Action 1215 as nominally expected in the GCC context. 1216 1217 This allows us to access the full range of bits passed in every case and 1218 has no impact on the callers side since each argument remains assigned 1219 the same single 64bit slot. 1220 1221 2. We retrieve the corresponding int and _Unwind_Action values within the 1222 routine for regular use with truncating conversions. This is a noop when 1223 called from the libgcc unwinder. 1224 1225 3. We assume we're called by the VMS CHF when unexpected bits are set in 1226 both those values. The incoming arguments are then real sigargs and 1227 mechargs pointers, which we then redirect to __gnat_handle_vms_condition 1228 for proper processing. 1229*/ 1230#if defined (VMS) && defined (__IA64) 1231typedef void * version_arg_t; 1232typedef void * phases_arg_t; 1233#else 1234typedef int version_arg_t; 1235typedef _Unwind_Action phases_arg_t; 1236#endif 1237 1238PERSONALITY_STORAGE _Unwind_Reason_Code 1239PERSONALITY_FUNCTION (version_arg_t, phases_arg_t, 1240 _Unwind_Exception_Class, _Unwind_Exception *, 1241 _Unwind_Context *); 1242 1243PERSONALITY_STORAGE _Unwind_Reason_Code 1244PERSONALITY_FUNCTION (version_arg_t version_arg, 1245 phases_arg_t phases_arg, 1246 _Unwind_Exception_Class uw_exception_class 1247 ATTRIBUTE_UNUSED, 1248 _Unwind_Exception *uw_exception, 1249 _Unwind_Context *uw_context) 1250{ 1251 /* Fetch the version and phases args with their nominal ABI types for later 1252 use. This is a noop everywhere except on ia64-vms when called from the 1253 Condition Handling Facility. */ 1254 int uw_version = (int) version_arg; 1255 _Unwind_Action uw_phases = (_Unwind_Action) phases_arg; 1256 1257 /* Check that we're called from the ABI context we expect, with a major 1258 possible variation on VMS for IA64. */ 1259 if (uw_version != 1) 1260 { 1261#if defined (VMS) && defined (__IA64) 1262 1263 /* Assume we're called with sigargs/mechargs arguments if really 1264 unexpected bits are set in our first two formals. Redirect to the 1265 GNAT condition handling code in this case. */ 1266 1267 extern long __gnat_handle_vms_condition (void *, void *); 1268 1269 unsigned int version_unexpected_bits_mask = 0xffffff00U; 1270 unsigned int phases_unexpected_bits_mask = 0xffffff00U; 1271 1272 if ((unsigned int)uw_version & version_unexpected_bits_mask 1273 && (unsigned int)uw_phases & phases_unexpected_bits_mask) 1274 return __gnat_handle_vms_condition (version_arg, phases_arg); 1275#endif 1276 1277 return _URC_FATAL_PHASE1_ERROR; 1278 } 1279 1280 return personality_body (uw_phases, uw_exception, uw_context); 1281} 1282 1283#else /* __ARM_EABI_UNWINDER__ */ 1284 1285PERSONALITY_STORAGE _Unwind_Reason_Code 1286PERSONALITY_FUNCTION (_Unwind_State state, 1287 struct _Unwind_Exception* ue_header, 1288 struct _Unwind_Context* uw_context); 1289 1290PERSONALITY_STORAGE _Unwind_Reason_Code 1291PERSONALITY_FUNCTION (_Unwind_State state, 1292 struct _Unwind_Exception* uw_exception, 1293 struct _Unwind_Context* uw_context) 1294{ 1295 _Unwind_Action uw_phases; 1296 1297 switch (state & _US_ACTION_MASK) 1298 { 1299 case _US_VIRTUAL_UNWIND_FRAME: 1300 /* Phase 1. */ 1301 uw_phases = _UA_SEARCH_PHASE; 1302 break; 1303 1304 case _US_UNWIND_FRAME_STARTING: 1305 /* Phase 2, to call a cleanup. */ 1306 uw_phases = _UA_CLEANUP_PHASE; 1307#if 0 1308 /* ??? We don't use UA_HANDLER_FRAME (except to debug). Futhermore, 1309 barrier_cache.sp isn't yet set. */ 1310 if (!(state & _US_FORCE_UNWIND) 1311 && (uw_exception->barrier_cache.sp 1312 == _Unwind_GetGR (uw_context, UNWIND_STACK_REG))) 1313 uw_phases |= _UA_HANDLER_FRAME; 1314#endif 1315 break; 1316 1317 case _US_UNWIND_FRAME_RESUME: 1318 /* Phase 2, called at the return of a cleanup. In the GNU 1319 implementation, there is nothing left to do, so we simply go on. */ 1320 return continue_unwind (uw_exception, uw_context); 1321 1322 default: 1323 return _URC_FAILURE; 1324 } 1325 uw_phases |= (state & _US_FORCE_UNWIND); 1326 1327 /* The dwarf unwinder assumes the context structure holds things like the 1328 function and LSDA pointers. The ARM implementation caches these in 1329 the exception header (UCB). To avoid rewriting everything we make a 1330 virtual scratch register point at the UCB. This is a GNU specific 1331 requirement. */ 1332 _Unwind_SetGR (uw_context, UNWIND_POINTER_REG, (_Unwind_Ptr) uw_exception); 1333 1334 return personality_body (uw_phases, uw_exception, uw_context); 1335} 1336#endif /* __ARM_EABI_UNWINDER__ */ 1337 1338/* Callback routine called by Unwind_ForcedUnwind to execute all the cleanup 1339 before exiting the task. */ 1340 1341_Unwind_Reason_Code 1342__gnat_cleanupunwind_handler (int version ATTRIBUTE_UNUSED, 1343 _Unwind_Action phases, 1344 _Unwind_Exception_Class eclass ATTRIBUTE_UNUSED, 1345 struct _Unwind_Exception *exception, 1346 struct _Unwind_Context *context ATTRIBUTE_UNUSED, 1347 void *arg ATTRIBUTE_UNUSED) 1348{ 1349 /* Terminate when the end of the stack is reached. */ 1350 if ((phases & _UA_END_OF_STACK) != 0 1351#if defined (__ia64__) && defined (__hpux__) && defined (USE_LIBUNWIND_EXCEPTIONS) 1352 /* Strictely follow the ia64 ABI: when end of stack is reached, 1353 the callback will be called with a NULL stack pointer. 1354 No need for that when using libgcc unwinder. */ 1355 || _Unwind_GetGR (context, 12) == 0 1356#endif 1357 ) 1358 __gnat_unhandled_except_handler (exception); 1359 1360 /* We know there is at least one cleanup further up. Return so that it 1361 is searched and entered, after which Unwind_Resume will be called 1362 and this hook will gain control again. */ 1363 return _URC_NO_REASON; 1364} 1365 1366/* Define the consistently named wrappers imported by Propagate_Exception. */ 1367 1368_Unwind_Reason_Code 1369__gnat_Unwind_RaiseException (_Unwind_Exception *e) 1370{ 1371#ifdef __USING_SJLJ_EXCEPTIONS__ 1372 return _Unwind_SjLj_RaiseException (e); 1373#else 1374 return _Unwind_RaiseException (e); 1375#endif 1376} 1377 1378_Unwind_Reason_Code 1379__gnat_Unwind_ForcedUnwind (_Unwind_Exception *e ATTRIBUTE_UNUSED, 1380 void *handler ATTRIBUTE_UNUSED, 1381 void *argument ATTRIBUTE_UNUSED) 1382{ 1383#ifdef __USING_SJLJ_EXCEPTIONS__ 1384 1385# if defined (__APPLE__) && defined (__arm__) 1386 /* There is not ForcedUnwind routine in arm-darwin system library. */ 1387 return _URC_FATAL_PHASE1_ERROR; 1388# else 1389 return _Unwind_SjLj_ForcedUnwind (e, handler, argument); 1390# endif 1391 1392#else 1393 return _Unwind_ForcedUnwind (e, handler, argument); 1394#endif 1395} 1396 1397#if defined (__SEH__) && !defined (__USING_SJLJ_EXCEPTIONS__) 1398 1399#define STATUS_USER_DEFINED (1U << 29) 1400 1401/* From unwind-seh.c. */ 1402#define GCC_MAGIC (('G' << 16) | ('C' << 8) | 'C') 1403#define GCC_EXCEPTION(TYPE) \ 1404 (STATUS_USER_DEFINED | ((TYPE) << 24) | GCC_MAGIC) 1405#define STATUS_GCC_THROW GCC_EXCEPTION (0) 1406 1407EXCEPTION_DISPOSITION __gnat_SEH_error_handler 1408 (struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*); 1409 1410struct Exception_Data * 1411__gnat_map_SEH (EXCEPTION_RECORD* ExceptionRecord, const char **msg); 1412 1413struct _Unwind_Exception * 1414__gnat_create_machine_occurrence_from_signal_handler (Exception_Id, 1415 const char *); 1416 1417/* Unwind opcodes. */ 1418#define UWOP_PUSH_NONVOL 0 1419#define UWOP_ALLOC_LARGE 1 1420#define UWOP_ALLOC_SMALL 2 1421#define UWOP_SET_FPREG 3 1422#define UWOP_SAVE_NONVOL 4 1423#define UWOP_SAVE_NONVOL_FAR 5 1424#define UWOP_SAVE_XMM128 8 1425#define UWOP_SAVE_XMM128_FAR 9 1426#define UWOP_PUSH_MACHFRAME 10 1427 1428/* Modify the IP value saved in the machine frame. This is really a kludge, 1429 that will be removed if we could propagate the Windows exception (and not 1430 the GCC one). 1431 What is very wrong is that the Windows unwinder will try to decode the 1432 instruction at IP, which isn't valid anymore after the adjust. */ 1433 1434static void 1435__gnat_adjust_context (unsigned char *unw, ULONG64 rsp) 1436{ 1437 unsigned int len; 1438 1439 /* Version = 1, no flags, no prologue. */ 1440 if (unw[0] != 1 || unw[1] != 0) 1441 return; 1442 len = unw[2]; 1443 /* No frame pointer. */ 1444 if (unw[3] != 0) 1445 return; 1446 unw += 4; 1447 while (len > 0) 1448 { 1449 /* Offset in prologue = 0. */ 1450 if (unw[0] != 0) 1451 return; 1452 switch (unw[1] & 0xf) 1453 { 1454 case UWOP_ALLOC_LARGE: 1455 /* Expect < 512KB. */ 1456 if ((unw[1] & 0xf0) != 0) 1457 return; 1458 rsp += *(unsigned short *)(unw + 2) * 8; 1459 len--; 1460 unw += 2; 1461 break; 1462 case UWOP_SAVE_NONVOL: 1463 case UWOP_SAVE_XMM128: 1464 len--; 1465 unw += 2; 1466 break; 1467 case UWOP_PUSH_MACHFRAME: 1468 { 1469 ULONG64 *rip; 1470 rip = (ULONG64 *)rsp; 1471 if ((unw[1] & 0xf0) == 0x10) 1472 rip++; 1473 /* Adjust rip. */ 1474 (*rip)++; 1475 } 1476 return; 1477 default: 1478 /* Unexpected. */ 1479 return; 1480 } 1481 unw += 2; 1482 len--; 1483 } 1484} 1485 1486EXCEPTION_DISPOSITION 1487__gnat_personality_seh0 (PEXCEPTION_RECORD ms_exc, void *this_frame, 1488 PCONTEXT ms_orig_context, 1489 PDISPATCHER_CONTEXT ms_disp) 1490{ 1491 /* Possibly transform run-time errors into Ada exceptions. As a small 1492 optimization, we call __gnat_SEH_error_handler only on non-user 1493 exceptions. */ 1494 if (!(ms_exc->ExceptionCode & STATUS_USER_DEFINED)) 1495 { 1496 struct Exception_Data *exception; 1497 const char *msg; 1498 ULONG64 excpip = (ULONG64) ms_exc->ExceptionAddress; 1499 1500 if (excpip != 0 1501 && excpip >= (ms_disp->ImageBase 1502 + ms_disp->FunctionEntry->BeginAddress) 1503 && excpip < (ms_disp->ImageBase 1504 + ms_disp->FunctionEntry->EndAddress)) 1505 { 1506 /* This is a fault in this function. We need to adjust the return 1507 address before raising the GCC exception. */ 1508 CONTEXT context; 1509 PRUNTIME_FUNCTION mf_func = NULL; 1510 ULONG64 mf_imagebase; 1511 ULONG64 mf_rsp = 0; 1512 1513 /* Get the context. */ 1514 RtlCaptureContext (&context); 1515 1516 while (1) 1517 { 1518 PRUNTIME_FUNCTION RuntimeFunction; 1519 ULONG64 ImageBase; 1520 VOID *HandlerData; 1521 ULONG64 EstablisherFrame; 1522 1523 /* Get function metadata. */ 1524 RuntimeFunction = RtlLookupFunctionEntry 1525 (context.Rip, &ImageBase, ms_disp->HistoryTable); 1526 if (RuntimeFunction == ms_disp->FunctionEntry) 1527 break; 1528 mf_func = RuntimeFunction; 1529 mf_imagebase = ImageBase; 1530 mf_rsp = context.Rsp; 1531 1532 if (!RuntimeFunction) 1533 { 1534 /* In case of failure, assume this is a leaf function. */ 1535 context.Rip = *(ULONG64 *) context.Rsp; 1536 context.Rsp += 8; 1537 } 1538 else 1539 { 1540 /* Unwind. */ 1541 RtlVirtualUnwind (0, ImageBase, context.Rip, RuntimeFunction, 1542 &context, &HandlerData, &EstablisherFrame, 1543 NULL); 1544 } 1545 1546 /* 0 means bottom of the stack. */ 1547 if (context.Rip == 0) 1548 { 1549 mf_func = NULL; 1550 break; 1551 } 1552 } 1553 if (mf_func != NULL) 1554 __gnat_adjust_context 1555 ((unsigned char *)(mf_imagebase + mf_func->UnwindData), mf_rsp); 1556 } 1557 1558 exception = __gnat_map_SEH (ms_exc, &msg); 1559 if (exception != NULL) 1560 { 1561 struct _Unwind_Exception *exc; 1562 1563 /* Directly convert the system exception to a GCC one. 1564 This is really breaking the API, but is necessary for stack size 1565 reasons: the normal way is to call Raise_From_Signal_Handler, 1566 which build the exception and calls _Unwind_RaiseException, which 1567 unwinds the stack and will call this personality routine. But 1568 the Windows unwinder needs about 2KB of stack. */ 1569 exc = __gnat_create_machine_occurrence_from_signal_handler 1570 (exception, msg); 1571 memset (exc->private_, 0, sizeof (exc->private_)); 1572 ms_exc->ExceptionCode = STATUS_GCC_THROW; 1573 ms_exc->NumberParameters = 1; 1574 ms_exc->ExceptionInformation[0] = (ULONG_PTR)exc; 1575 } 1576 1577 } 1578 1579 return _GCC_specific_handler (ms_exc, this_frame, ms_orig_context, 1580 ms_disp, __gnat_personality_imp); 1581} 1582#endif /* SEH */ 1583 1584#if !defined (__USING_SJLJ_EXCEPTIONS__) 1585/* Size of the _Unwind_Exception structure. This is used by g-cppexc to get 1586 the offset to the C++ object. */ 1587 1588const int __gnat_unwind_exception_size = sizeof (_Unwind_Exception); 1589#endif 1590