except.c revision 50397
1/* Implements exception handling. 2 Copyright (C) 1989, 92-97, 1998 Free Software Foundation, Inc. 3 Contributed by Mike Stump <mrs@cygnus.com>. 4 5This file is part of GNU CC. 6 7GNU CC is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2, or (at your option) 10any later version. 11 12GNU CC is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GNU CC; see the file COPYING. If not, write to 19the Free Software Foundation, 59 Temple Place - Suite 330, 20Boston, MA 02111-1307, USA. */ 21 22 23/* An exception is an event that can be signaled from within a 24 function. This event can then be "caught" or "trapped" by the 25 callers of this function. This potentially allows program flow to 26 be transferred to any arbitrary code associated with a function call 27 several levels up the stack. 28 29 The intended use for this mechanism is for signaling "exceptional 30 events" in an out-of-band fashion, hence its name. The C++ language 31 (and many other OO-styled or functional languages) practically 32 requires such a mechanism, as otherwise it becomes very difficult 33 or even impossible to signal failure conditions in complex 34 situations. The traditional C++ example is when an error occurs in 35 the process of constructing an object; without such a mechanism, it 36 is impossible to signal that the error occurs without adding global 37 state variables and error checks around every object construction. 38 39 The act of causing this event to occur is referred to as "throwing 40 an exception". (Alternate terms include "raising an exception" or 41 "signaling an exception".) The term "throw" is used because control 42 is returned to the callers of the function that is signaling the 43 exception, and thus there is the concept of "throwing" the 44 exception up the call stack. 45 46 There are two major codegen options for exception handling. The 47 flag -fsjlj-exceptions can be used to select the setjmp/longjmp 48 approach, which is the default. -fno-sjlj-exceptions can be used to 49 get the PC range table approach. While this is a compile time 50 flag, an entire application must be compiled with the same codegen 51 option. The first is a PC range table approach, the second is a 52 setjmp/longjmp based scheme. We will first discuss the PC range 53 table approach, after that, we will discuss the setjmp/longjmp 54 based approach. 55 56 It is appropriate to speak of the "context of a throw". This 57 context refers to the address where the exception is thrown from, 58 and is used to determine which exception region will handle the 59 exception. 60 61 Regions of code within a function can be marked such that if it 62 contains the context of a throw, control will be passed to a 63 designated "exception handler". These areas are known as "exception 64 regions". Exception regions cannot overlap, but they can be nested 65 to any arbitrary depth. Also, exception regions cannot cross 66 function boundaries. 67 68 Exception handlers can either be specified by the user (which we 69 will call a "user-defined handler") or generated by the compiler 70 (which we will designate as a "cleanup"). Cleanups are used to 71 perform tasks such as destruction of objects allocated on the 72 stack. 73 74 In the current implementation, cleanups are handled by allocating an 75 exception region for the area that the cleanup is designated for, 76 and the handler for the region performs the cleanup and then 77 rethrows the exception to the outer exception region. From the 78 standpoint of the current implementation, there is little 79 distinction made between a cleanup and a user-defined handler, and 80 the phrase "exception handler" can be used to refer to either one 81 equally well. (The section "Future Directions" below discusses how 82 this will change). 83 84 Each object file that is compiled with exception handling contains 85 a static array of exception handlers named __EXCEPTION_TABLE__. 86 Each entry contains the starting and ending addresses of the 87 exception region, and the address of the handler designated for 88 that region. 89 90 If the target does not use the DWARF 2 frame unwind information, at 91 program startup each object file invokes a function named 92 __register_exceptions with the address of its local 93 __EXCEPTION_TABLE__. __register_exceptions is defined in libgcc2.c, and 94 is responsible for recording all of the exception regions into one list 95 (which is kept in a static variable named exception_table_list). 96 97 On targets that support crtstuff.c, the unwind information 98 is stored in a section named .eh_frame and the information for the 99 entire shared object or program is registered with a call to 100 __register_frame_info. On other targets, the information for each 101 translation unit is registered from the file generated by collect2. 102 __register_frame_info is defined in frame.c, and is responsible for 103 recording all of the unwind regions into one list (which is kept in a 104 static variable named unwind_table_list). 105 106 The function __throw is actually responsible for doing the 107 throw. On machines that have unwind info support, __throw is generated 108 by code in libgcc2.c, otherwise __throw is generated on a 109 per-object-file basis for each source file compiled with 110 -fexceptions by the C++ frontend. Before __throw is invoked, 111 the current context of the throw needs to be placed in the global 112 variable __eh_pc. 113 114 __throw attempts to find the appropriate exception handler for the 115 PC value stored in __eh_pc by calling __find_first_exception_table_match 116 (which is defined in libgcc2.c). If __find_first_exception_table_match 117 finds a relevant handler, __throw transfers control directly to it. 118 119 If a handler for the context being thrown from can't be found, __throw 120 walks (see Walking the stack below) the stack up the dynamic call chain to 121 continue searching for an appropriate exception handler based upon the 122 caller of the function it last sought a exception handler for. It stops 123 then either an exception handler is found, or when the top of the 124 call chain is reached. 125 126 If no handler is found, an external library function named 127 __terminate is called. If a handler is found, then we restart 128 our search for a handler at the end of the call chain, and repeat 129 the search process, but instead of just walking up the call chain, 130 we unwind the call chain as we walk up it. 131 132 Internal implementation details: 133 134 To associate a user-defined handler with a block of statements, the 135 function expand_start_try_stmts is used to mark the start of the 136 block of statements with which the handler is to be associated 137 (which is known as a "try block"). All statements that appear 138 afterwards will be associated with the try block. 139 140 A call to expand_start_all_catch marks the end of the try block, 141 and also marks the start of the "catch block" (the user-defined 142 handler) associated with the try block. 143 144 This user-defined handler will be invoked for *every* exception 145 thrown with the context of the try block. It is up to the handler 146 to decide whether or not it wishes to handle any given exception, 147 as there is currently no mechanism in this implementation for doing 148 this. (There are plans for conditionally processing an exception 149 based on its "type", which will provide a language-independent 150 mechanism). 151 152 If the handler chooses not to process the exception (perhaps by 153 looking at an "exception type" or some other additional data 154 supplied with the exception), it can fall through to the end of the 155 handler. expand_end_all_catch and expand_leftover_cleanups 156 add additional code to the end of each handler to take care of 157 rethrowing to the outer exception handler. 158 159 The handler also has the option to continue with "normal flow of 160 code", or in other words to resume executing at the statement 161 immediately after the end of the exception region. The variable 162 caught_return_label_stack contains a stack of labels, and jumping 163 to the topmost entry's label via expand_goto will resume normal 164 flow to the statement immediately after the end of the exception 165 region. If the handler falls through to the end, the exception will 166 be rethrown to the outer exception region. 167 168 The instructions for the catch block are kept as a separate 169 sequence, and will be emitted at the end of the function along with 170 the handlers specified via expand_eh_region_end. The end of the 171 catch block is marked with expand_end_all_catch. 172 173 Any data associated with the exception must currently be handled by 174 some external mechanism maintained in the frontend. For example, 175 the C++ exception mechanism passes an arbitrary value along with 176 the exception, and this is handled in the C++ frontend by using a 177 global variable to hold the value. (This will be changing in the 178 future.) 179 180 The mechanism in C++ for handling data associated with the 181 exception is clearly not thread-safe. For a thread-based 182 environment, another mechanism must be used (possibly using a 183 per-thread allocation mechanism if the size of the area that needs 184 to be allocated isn't known at compile time.) 185 186 Internally-generated exception regions (cleanups) are marked by 187 calling expand_eh_region_start to mark the start of the region, 188 and expand_eh_region_end (handler) is used to both designate the 189 end of the region and to associate a specified handler/cleanup with 190 the region. The rtl code in HANDLER will be invoked whenever an 191 exception occurs in the region between the calls to 192 expand_eh_region_start and expand_eh_region_end. After HANDLER is 193 executed, additional code is emitted to handle rethrowing the 194 exception to the outer exception handler. The code for HANDLER will 195 be emitted at the end of the function. 196 197 TARGET_EXPRs can also be used to designate exception regions. A 198 TARGET_EXPR gives an unwind-protect style interface commonly used 199 in functional languages such as LISP. The associated expression is 200 evaluated, and whether or not it (or any of the functions that it 201 calls) throws an exception, the protect expression is always 202 invoked. This implementation takes care of the details of 203 associating an exception table entry with the expression and 204 generating the necessary code (it actually emits the protect 205 expression twice, once for normal flow and once for the exception 206 case). As for the other handlers, the code for the exception case 207 will be emitted at the end of the function. 208 209 Cleanups can also be specified by using add_partial_entry (handler) 210 and end_protect_partials. add_partial_entry creates the start of 211 a new exception region; HANDLER will be invoked if an exception is 212 thrown with the context of the region between the calls to 213 add_partial_entry and end_protect_partials. end_protect_partials is 214 used to mark the end of these regions. add_partial_entry can be 215 called as many times as needed before calling end_protect_partials. 216 However, end_protect_partials should only be invoked once for each 217 group of calls to add_partial_entry as the entries are queued 218 and all of the outstanding entries are processed simultaneously 219 when end_protect_partials is invoked. Similarly to the other 220 handlers, the code for HANDLER will be emitted at the end of the 221 function. 222 223 The generated RTL for an exception region includes 224 NOTE_INSN_EH_REGION_BEG and NOTE_INSN_EH_REGION_END notes that mark 225 the start and end of the exception region. A unique label is also 226 generated at the start of the exception region, which is available 227 by looking at the ehstack variable. The topmost entry corresponds 228 to the current region. 229 230 In the current implementation, an exception can only be thrown from 231 a function call (since the mechanism used to actually throw an 232 exception involves calling __throw). If an exception region is 233 created but no function calls occur within that region, the region 234 can be safely optimized away (along with its exception handlers) 235 since no exceptions can ever be caught in that region. This 236 optimization is performed unless -fasynchronous-exceptions is 237 given. If the user wishes to throw from a signal handler, or other 238 asynchronous place, -fasynchronous-exceptions should be used when 239 compiling for maximally correct code, at the cost of additional 240 exception regions. Using -fasynchronous-exceptions only produces 241 code that is reasonably safe in such situations, but a correct 242 program cannot rely upon this working. It can be used in failsafe 243 code, where trying to continue on, and proceeding with potentially 244 incorrect results is better than halting the program. 245 246 247 Walking the stack: 248 249 The stack is walked by starting with a pointer to the current 250 frame, and finding the pointer to the callers frame. The unwind info 251 tells __throw how to find it. 252 253 Unwinding the stack: 254 255 When we use the term unwinding the stack, we mean undoing the 256 effects of the function prologue in a controlled fashion so that we 257 still have the flow of control. Otherwise, we could just return 258 (jump to the normal end of function epilogue). 259 260 This is done in __throw in libgcc2.c when we know that a handler exists 261 in a frame higher up the call stack than its immediate caller. 262 263 To unwind, we find the unwind data associated with the frame, if any. 264 If we don't find any, we call the library routine __terminate. If we do 265 find it, we use the information to copy the saved register values from 266 that frame into the register save area in the frame for __throw, return 267 into a stub which updates the stack pointer, and jump to the handler. 268 The normal function epilogue for __throw handles restoring the saved 269 values into registers. 270 271 When unwinding, we use this method if we know it will 272 work (if DWARF2_UNWIND_INFO is defined). Otherwise, we know that 273 an inline unwinder will have been emitted for any function that 274 __unwind_function cannot unwind. The inline unwinder appears as a 275 normal exception handler for the entire function, for any function 276 that we know cannot be unwound by __unwind_function. We inform the 277 compiler of whether a function can be unwound with 278 __unwind_function by having DOESNT_NEED_UNWINDER evaluate to true 279 when the unwinder isn't needed. __unwind_function is used as an 280 action of last resort. If no other method can be used for 281 unwinding, __unwind_function is used. If it cannot unwind, it 282 should call __terminate. 283 284 By default, if the target-specific backend doesn't supply a definition 285 for __unwind_function and doesn't support DWARF2_UNWIND_INFO, inlined 286 unwinders will be used instead. The main tradeoff here is in text space 287 utilization. Obviously, if inline unwinders have to be generated 288 repeatedly, this uses much more space than if a single routine is used. 289 290 However, it is simply not possible on some platforms to write a 291 generalized routine for doing stack unwinding without having some 292 form of additional data associated with each function. The current 293 implementation can encode this data in the form of additional 294 machine instructions or as static data in tabular form. The later 295 is called the unwind data. 296 297 The backend macro DOESNT_NEED_UNWINDER is used to conditionalize whether 298 or not per-function unwinders are needed. If DOESNT_NEED_UNWINDER is 299 defined and has a non-zero value, a per-function unwinder is not emitted 300 for the current function. If the static unwind data is supported, then 301 a per-function unwinder is not emitted. 302 303 On some platforms it is possible that neither __unwind_function 304 nor inlined unwinders are available. For these platforms it is not 305 possible to throw through a function call, and abort will be 306 invoked instead of performing the throw. 307 308 The reason the unwind data may be needed is that on some platforms 309 the order and types of data stored on the stack can vary depending 310 on the type of function, its arguments and returned values, and the 311 compilation options used (optimization versus non-optimization, 312 -fomit-frame-pointer, processor variations, etc). 313 314 Unfortunately, this also means that throwing through functions that 315 aren't compiled with exception handling support will still not be 316 possible on some platforms. This problem is currently being 317 investigated, but no solutions have been found that do not imply 318 some unacceptable performance penalties. 319 320 Future directions: 321 322 Currently __throw makes no differentiation between cleanups and 323 user-defined exception regions. While this makes the implementation 324 simple, it also implies that it is impossible to determine if a 325 user-defined exception handler exists for a given exception without 326 completely unwinding the stack in the process. This is undesirable 327 from the standpoint of debugging, as ideally it would be possible 328 to trap unhandled exceptions in the debugger before the process of 329 unwinding has even started. 330 331 This problem can be solved by marking user-defined handlers in a 332 special way (probably by adding additional bits to exception_table_list). 333 A two-pass scheme could then be used by __throw to iterate 334 through the table. The first pass would search for a relevant 335 user-defined handler for the current context of the throw, and if 336 one is found, the second pass would then invoke all needed cleanups 337 before jumping to the user-defined handler. 338 339 Many languages (including C++ and Ada) make execution of a 340 user-defined handler conditional on the "type" of the exception 341 thrown. (The type of the exception is actually the type of the data 342 that is thrown with the exception.) It will thus be necessary for 343 __throw to be able to determine if a given user-defined 344 exception handler will actually be executed, given the type of 345 exception. 346 347 One scheme is to add additional information to exception_table_list 348 as to the types of exceptions accepted by each handler. __throw 349 can do the type comparisons and then determine if the handler is 350 actually going to be executed. 351 352 There is currently no significant level of debugging support 353 available, other than to place a breakpoint on __throw. While 354 this is sufficient in most cases, it would be helpful to be able to 355 know where a given exception was going to be thrown to before it is 356 actually thrown, and to be able to choose between stopping before 357 every exception region (including cleanups), or just user-defined 358 exception regions. This should be possible to do in the two-pass 359 scheme by adding additional labels to __throw for appropriate 360 breakpoints, and additional debugger commands could be added to 361 query various state variables to determine what actions are to be 362 performed next. 363 364 Another major problem that is being worked on is the issue with stack 365 unwinding on various platforms. Currently the only platforms that have 366 support for the generation of a generic unwinder are the SPARC and MIPS. 367 All other ports require per-function unwinders, which produce large 368 amounts of code bloat. 369 370 For setjmp/longjmp based exception handling, some of the details 371 are as above, but there are some additional details. This section 372 discusses the details. 373 374 We don't use NOTE_INSN_EH_REGION_{BEG,END} pairs. We don't 375 optimize EH regions yet. We don't have to worry about machine 376 specific issues with unwinding the stack, as we rely upon longjmp 377 for all the machine specific details. There is no variable context 378 of a throw, just the one implied by the dynamic handler stack 379 pointed to by the dynamic handler chain. There is no exception 380 table, and no calls to __register_exceptions. __sjthrow is used 381 instead of __throw, and it works by using the dynamic handler 382 chain, and longjmp. -fasynchronous-exceptions has no effect, as 383 the elimination of trivial exception regions is not yet performed. 384 385 A frontend can set protect_cleanup_actions_with_terminate when all 386 the cleanup actions should be protected with an EH region that 387 calls terminate when an unhandled exception is throw. C++ does 388 this, Ada does not. */ 389 390 391#include "config.h" 392#include "defaults.h" 393#include "eh-common.h" 394#include "system.h" 395#include "rtl.h" 396#include "tree.h" 397#include "flags.h" 398#include "except.h" 399#include "function.h" 400#include "insn-flags.h" 401#include "expr.h" 402#include "insn-codes.h" 403#include "regs.h" 404#include "hard-reg-set.h" 405#include "insn-config.h" 406#include "recog.h" 407#include "output.h" 408#include "toplev.h" 409 410/* One to use setjmp/longjmp method of generating code for exception 411 handling. */ 412 413int exceptions_via_longjmp = 2; 414 415/* One to enable asynchronous exception support. */ 416 417int asynchronous_exceptions = 0; 418 419/* One to protect cleanup actions with a handler that calls 420 __terminate, zero otherwise. */ 421 422int protect_cleanup_actions_with_terminate; 423 424/* A list of labels used for exception handlers. Created by 425 find_exception_handler_labels for the optimization passes. */ 426 427rtx exception_handler_labels; 428 429/* The EH context. Nonzero if the function has already 430 fetched a pointer to the EH context for exception handling. */ 431 432rtx current_function_ehc; 433 434/* A stack used for keeping track of the currently active exception 435 handling region. As each exception region is started, an entry 436 describing the region is pushed onto this stack. The current 437 region can be found by looking at the top of the stack, and as we 438 exit regions, the corresponding entries are popped. 439 440 Entries cannot overlap; they can be nested. So there is only one 441 entry at most that corresponds to the current instruction, and that 442 is the entry on the top of the stack. */ 443 444static struct eh_stack ehstack; 445 446 447/* This stack is used to represent what the current eh region is 448 for the catch blocks beings processed */ 449 450static struct eh_stack catchstack; 451 452/* A queue used for tracking which exception regions have closed but 453 whose handlers have not yet been expanded. Regions are emitted in 454 groups in an attempt to improve paging performance. 455 456 As we exit a region, we enqueue a new entry. The entries are then 457 dequeued during expand_leftover_cleanups and expand_start_all_catch, 458 459 We should redo things so that we either take RTL for the handler, 460 or we expand the handler expressed as a tree immediately at region 461 end time. */ 462 463static struct eh_queue ehqueue; 464 465/* Insns for all of the exception handlers for the current function. 466 They are currently emitted by the frontend code. */ 467 468rtx catch_clauses; 469 470/* A TREE_CHAINed list of handlers for regions that are not yet 471 closed. The TREE_VALUE of each entry contains the handler for the 472 corresponding entry on the ehstack. */ 473 474static tree protect_list; 475 476/* Stacks to keep track of various labels. */ 477 478/* Keeps track of the label to resume to should one want to resume 479 normal control flow out of a handler (instead of, say, returning to 480 the caller of the current function or exiting the program). */ 481 482struct label_node *caught_return_label_stack = NULL; 483 484/* Keeps track of the label used as the context of a throw to rethrow an 485 exception to the outer exception region. */ 486 487struct label_node *outer_context_label_stack = NULL; 488 489/* A random data area for the front end's own use. */ 490 491struct label_node *false_label_stack = NULL; 492 493static void push_eh_entry PROTO((struct eh_stack *)); 494static struct eh_entry * pop_eh_entry PROTO((struct eh_stack *)); 495static void enqueue_eh_entry PROTO((struct eh_queue *, struct eh_entry *)); 496static struct eh_entry * dequeue_eh_entry PROTO((struct eh_queue *)); 497static rtx call_get_eh_context PROTO((void)); 498static void start_dynamic_cleanup PROTO((tree, tree)); 499static void start_dynamic_handler PROTO((void)); 500static void expand_rethrow PROTO((rtx)); 501static void output_exception_table_entry PROTO((FILE *, int)); 502static int can_throw PROTO((rtx)); 503static rtx scan_region PROTO((rtx, int, int *)); 504static void eh_regs PROTO((rtx *, rtx *, int)); 505static void set_insn_eh_region PROTO((rtx *, int)); 506#ifdef DONT_USE_BUILTIN_SETJMP 507static void jumpif_rtx PROTO((rtx, rtx)); 508#endif 509 510 511rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx)); 512 513/* Various support routines to manipulate the various data structures 514 used by the exception handling code. */ 515 516/* Push a label entry onto the given STACK. */ 517 518void 519push_label_entry (stack, rlabel, tlabel) 520 struct label_node **stack; 521 rtx rlabel; 522 tree tlabel; 523{ 524 struct label_node *newnode 525 = (struct label_node *) xmalloc (sizeof (struct label_node)); 526 527 if (rlabel) 528 newnode->u.rlabel = rlabel; 529 else 530 newnode->u.tlabel = tlabel; 531 newnode->chain = *stack; 532 *stack = newnode; 533} 534 535/* Pop a label entry from the given STACK. */ 536 537rtx 538pop_label_entry (stack) 539 struct label_node **stack; 540{ 541 rtx label; 542 struct label_node *tempnode; 543 544 if (! *stack) 545 return NULL_RTX; 546 547 tempnode = *stack; 548 label = tempnode->u.rlabel; 549 *stack = (*stack)->chain; 550 free (tempnode); 551 552 return label; 553} 554 555/* Return the top element of the given STACK. */ 556 557tree 558top_label_entry (stack) 559 struct label_node **stack; 560{ 561 if (! *stack) 562 return NULL_TREE; 563 564 return (*stack)->u.tlabel; 565} 566 567/* get an exception label. These must be on the permanent obstack */ 568 569rtx 570gen_exception_label () 571{ 572 rtx lab; 573 574 push_obstacks_nochange (); 575 end_temporary_allocation (); 576 lab = gen_label_rtx (); 577 pop_obstacks (); 578 return lab; 579} 580 581/* Push a new eh_node entry onto STACK. */ 582 583static void 584push_eh_entry (stack) 585 struct eh_stack *stack; 586{ 587 struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node)); 588 struct eh_entry *entry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry)); 589 590 entry->outer_context = gen_label_rtx (); 591 entry->finalization = NULL_TREE; 592 entry->label_used = 0; 593 entry->exception_handler_label = gen_exception_label (); 594 595 node->entry = entry; 596 node->chain = stack->top; 597 stack->top = node; 598} 599 600/* push an existing entry onto a stack. */ 601static void 602push_entry (stack, entry) 603 struct eh_stack *stack; 604 struct eh_entry *entry; 605{ 606 struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node)); 607 node->entry = entry; 608 node->chain = stack->top; 609 stack->top = node; 610} 611 612/* Pop an entry from the given STACK. */ 613 614static struct eh_entry * 615pop_eh_entry (stack) 616 struct eh_stack *stack; 617{ 618 struct eh_node *tempnode; 619 struct eh_entry *tempentry; 620 621 tempnode = stack->top; 622 tempentry = tempnode->entry; 623 stack->top = stack->top->chain; 624 free (tempnode); 625 626 return tempentry; 627} 628 629/* Enqueue an ENTRY onto the given QUEUE. */ 630 631static void 632enqueue_eh_entry (queue, entry) 633 struct eh_queue *queue; 634 struct eh_entry *entry; 635{ 636 struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node)); 637 638 node->entry = entry; 639 node->chain = NULL; 640 641 if (queue->head == NULL) 642 { 643 queue->head = node; 644 } 645 else 646 { 647 queue->tail->chain = node; 648 } 649 queue->tail = node; 650} 651 652/* Dequeue an entry from the given QUEUE. */ 653 654static struct eh_entry * 655dequeue_eh_entry (queue) 656 struct eh_queue *queue; 657{ 658 struct eh_node *tempnode; 659 struct eh_entry *tempentry; 660 661 if (queue->head == NULL) 662 return NULL; 663 664 tempnode = queue->head; 665 queue->head = queue->head->chain; 666 667 tempentry = tempnode->entry; 668 free (tempnode); 669 670 return tempentry; 671} 672 673static void 674receive_exception_label (handler_label) 675 rtx handler_label; 676{ 677 emit_label (handler_label); 678 679#ifdef HAVE_exception_receiver 680 if (! exceptions_via_longjmp) 681 if (HAVE_exception_receiver) 682 emit_insn (gen_exception_receiver ()); 683#endif 684 685#ifdef HAVE_nonlocal_goto_receiver 686 if (! exceptions_via_longjmp) 687 if (HAVE_nonlocal_goto_receiver) 688 emit_insn (gen_nonlocal_goto_receiver ()); 689#endif 690} 691 692 693struct func_eh_entry 694{ 695 int range_number; /* EH region number from EH NOTE insn's */ 696 struct handler_info *handlers; 697}; 698 699 700/* table of function eh regions */ 701static struct func_eh_entry *function_eh_regions = NULL; 702static int num_func_eh_entries = 0; 703static int current_func_eh_entry = 0; 704 705#define SIZE_FUNC_EH(X) (sizeof (struct func_eh_entry) * X) 706 707/* Add a new eh_entry for this function, and base it off of the information 708 in the EH_ENTRY parameter. A NULL parameter is invalid. The number 709 returned is an number which uniquely identifies this exception range. */ 710 711int 712new_eh_region_entry (note_eh_region) 713 int note_eh_region; 714{ 715 if (current_func_eh_entry == num_func_eh_entries) 716 { 717 if (num_func_eh_entries == 0) 718 { 719 function_eh_regions = 720 (struct func_eh_entry *) malloc (SIZE_FUNC_EH (50)); 721 num_func_eh_entries = 50; 722 } 723 else 724 { 725 num_func_eh_entries = num_func_eh_entries * 3 / 2; 726 function_eh_regions = (struct func_eh_entry *) 727 realloc (function_eh_regions, SIZE_FUNC_EH (num_func_eh_entries)); 728 } 729 } 730 function_eh_regions[current_func_eh_entry].range_number = note_eh_region; 731 function_eh_regions[current_func_eh_entry].handlers = NULL; 732 733 return current_func_eh_entry++; 734} 735 736/* Add new handler information to an exception range. The first parameter 737 specifies the range number (returned from new_eh_entry()). The second 738 parameter specifies the handler. By default the handler is inserted at 739 the end of the list. A handler list may contain only ONE NULL_TREE 740 typeinfo entry. Regardless where it is positioned, a NULL_TREE entry 741 is always output as the LAST handler in the exception table for a region. */ 742 743void 744add_new_handler (region, newhandler) 745 int region; 746 struct handler_info *newhandler; 747{ 748 struct handler_info *last; 749 750 newhandler->next = NULL; 751 last = function_eh_regions[region].handlers; 752 if (last == NULL) 753 function_eh_regions[region].handlers = newhandler; 754 else 755 { 756 for ( ; last->next != NULL; last = last->next) 757 ; 758 last->next = newhandler; 759 } 760} 761 762/* Remove a handler label. The handler label is being deleted, so all 763 regions which reference this handler should have it removed from their 764 list of possible handlers. Any region which has the final handler 765 removed can be deleted. */ 766 767void remove_handler (removing_label) 768 rtx removing_label; 769{ 770 struct handler_info *handler, *last; 771 int x; 772 for (x = 0 ; x < current_func_eh_entry; ++x) 773 { 774 last = NULL; 775 handler = function_eh_regions[x].handlers; 776 for ( ; handler; last = handler, handler = handler->next) 777 if (handler->handler_label == removing_label) 778 { 779 if (last) 780 { 781 last->next = handler->next; 782 handler = last; 783 } 784 else 785 function_eh_regions[x].handlers = handler->next; 786 } 787 } 788} 789 790/* This function will return a malloc'd pointer to an array of 791 void pointer representing the runtime match values that 792 currently exist in all regions. */ 793 794int 795find_all_handler_type_matches (array) 796 void ***array; 797{ 798 struct handler_info *handler, *last; 799 int x,y; 800 void *val; 801 void **ptr; 802 int max_ptr; 803 int n_ptr = 0; 804 805 *array = NULL; 806 807 if (!doing_eh (0) || ! flag_new_exceptions) 808 return 0; 809 810 max_ptr = 100; 811 ptr = (void **)malloc (max_ptr * sizeof (void *)); 812 813 if (ptr == NULL) 814 return 0; 815 816 for (x = 0 ; x < current_func_eh_entry; x++) 817 { 818 last = NULL; 819 handler = function_eh_regions[x].handlers; 820 for ( ; handler; last = handler, handler = handler->next) 821 { 822 val = handler->type_info; 823 if (val != NULL && val != CATCH_ALL_TYPE) 824 { 825 /* See if this match value has already been found. */ 826 for (y = 0; y < n_ptr; y++) 827 if (ptr[y] == val) 828 break; 829 830 /* If we break early, we already found this value. */ 831 if (y < n_ptr) 832 continue; 833 834 /* Do we need to allocate more space? */ 835 if (n_ptr >= max_ptr) 836 { 837 max_ptr += max_ptr / 2; 838 ptr = (void **)realloc (ptr, max_ptr * sizeof (void *)); 839 if (ptr == NULL) 840 return 0; 841 } 842 ptr[n_ptr] = val; 843 n_ptr++; 844 } 845 } 846 } 847 *array = ptr; 848 return n_ptr; 849} 850 851/* Create a new handler structure initialized with the handler label and 852 typeinfo fields passed in. */ 853 854struct handler_info * 855get_new_handler (handler, typeinfo) 856 rtx handler; 857 void *typeinfo; 858{ 859 struct handler_info* ptr; 860 ptr = (struct handler_info *) malloc (sizeof (struct handler_info)); 861 ptr->handler_label = handler; 862 ptr->type_info = typeinfo; 863 ptr->next = NULL; 864 865 return ptr; 866} 867 868 869 870/* Find the index in function_eh_regions associated with a NOTE region. If 871 the region cannot be found, a -1 is returned. This should never happen! */ 872 873int 874find_func_region (insn_region) 875 int insn_region; 876{ 877 int x; 878 for (x = 0; x < current_func_eh_entry; x++) 879 if (function_eh_regions[x].range_number == insn_region) 880 return x; 881 882 return -1; 883} 884 885/* Get a pointer to the first handler in an exception region's list. */ 886 887struct handler_info * 888get_first_handler (region) 889 int region; 890{ 891 return function_eh_regions[find_func_region (region)].handlers; 892} 893 894/* Clean out the function_eh_region table and free all memory */ 895 896static void 897clear_function_eh_region () 898{ 899 int x; 900 struct handler_info *ptr, *next; 901 for (x = 0; x < current_func_eh_entry; x++) 902 for (ptr = function_eh_regions[x].handlers; ptr != NULL; ptr = next) 903 { 904 next = ptr->next; 905 free (ptr); 906 } 907 free (function_eh_regions); 908 num_func_eh_entries = 0; 909 current_func_eh_entry = 0; 910} 911 912/* Make a duplicate of an exception region by copying all the handlers 913 for an exception region. Return the new handler index. */ 914 915int 916duplicate_handlers (old_note_eh_region, new_note_eh_region) 917 int old_note_eh_region, new_note_eh_region; 918{ 919 struct handler_info *ptr, *new_ptr; 920 int new_region, region; 921 922 region = find_func_region (old_note_eh_region); 923 if (region == -1) 924 error ("Cannot duplicate non-existant exception region."); 925 926 if (find_func_region (new_note_eh_region) != -1) 927 error ("Cannot duplicate EH region because new note region already exists"); 928 929 new_region = new_eh_region_entry (new_note_eh_region); 930 ptr = function_eh_regions[region].handlers; 931 932 for ( ; ptr; ptr = ptr->next) 933 { 934 new_ptr = get_new_handler (ptr->handler_label, ptr->type_info); 935 add_new_handler (new_region, new_ptr); 936 } 937 938 return new_region; 939} 940 941 942/* Routine to see if exception handling is turned on. 943 DO_WARN is non-zero if we want to inform the user that exception 944 handling is turned off. 945 946 This is used to ensure that -fexceptions has been specified if the 947 compiler tries to use any exception-specific functions. */ 948 949int 950doing_eh (do_warn) 951 int do_warn; 952{ 953 if (! flag_exceptions) 954 { 955 static int warned = 0; 956 if (! warned && do_warn) 957 { 958 error ("exception handling disabled, use -fexceptions to enable"); 959 warned = 1; 960 } 961 return 0; 962 } 963 return 1; 964} 965 966/* Given a return address in ADDR, determine the address we should use 967 to find the corresponding EH region. */ 968 969rtx 970eh_outer_context (addr) 971 rtx addr; 972{ 973 /* First mask out any unwanted bits. */ 974#ifdef MASK_RETURN_ADDR 975 expand_and (addr, MASK_RETURN_ADDR, addr); 976#endif 977 978 /* Then adjust to find the real return address. */ 979#if defined (RETURN_ADDR_OFFSET) 980 addr = plus_constant (addr, RETURN_ADDR_OFFSET); 981#endif 982 983 return addr; 984} 985 986/* Start a new exception region for a region of code that has a 987 cleanup action and push the HANDLER for the region onto 988 protect_list. All of the regions created with add_partial_entry 989 will be ended when end_protect_partials is invoked. */ 990 991void 992add_partial_entry (handler) 993 tree handler; 994{ 995 expand_eh_region_start (); 996 997 /* Make sure the entry is on the correct obstack. */ 998 push_obstacks_nochange (); 999 resume_temporary_allocation (); 1000 1001 /* Because this is a cleanup action, we may have to protect the handler 1002 with __terminate. */ 1003 handler = protect_with_terminate (handler); 1004 1005 protect_list = tree_cons (NULL_TREE, handler, protect_list); 1006 pop_obstacks (); 1007} 1008 1009/* Emit code to get EH context to current function. */ 1010 1011static rtx 1012call_get_eh_context () 1013{ 1014 static tree fn; 1015 tree expr; 1016 1017 if (fn == NULL_TREE) 1018 { 1019 tree fntype; 1020 fn = get_identifier ("__get_eh_context"); 1021 push_obstacks_nochange (); 1022 end_temporary_allocation (); 1023 fntype = build_pointer_type (build_pointer_type 1024 (build_pointer_type (void_type_node))); 1025 fntype = build_function_type (fntype, NULL_TREE); 1026 fn = build_decl (FUNCTION_DECL, fn, fntype); 1027 DECL_EXTERNAL (fn) = 1; 1028 TREE_PUBLIC (fn) = 1; 1029 DECL_ARTIFICIAL (fn) = 1; 1030 TREE_READONLY (fn) = 1; 1031 make_decl_rtl (fn, NULL_PTR, 1); 1032 assemble_external (fn); 1033 pop_obstacks (); 1034 } 1035 1036 expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); 1037 expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)), 1038 expr, NULL_TREE, NULL_TREE); 1039 TREE_SIDE_EFFECTS (expr) = 1; 1040 1041 return copy_to_reg (expand_expr (expr, NULL_RTX, VOIDmode, 0)); 1042} 1043 1044/* Get a reference to the EH context. 1045 We will only generate a register for the current function EH context here, 1046 and emit a USE insn to mark that this is a EH context register. 1047 1048 Later, emit_eh_context will emit needed call to __get_eh_context 1049 in libgcc2, and copy the value to the register we have generated. */ 1050 1051rtx 1052get_eh_context () 1053{ 1054 if (current_function_ehc == 0) 1055 { 1056 rtx insn; 1057 1058 current_function_ehc = gen_reg_rtx (Pmode); 1059 1060 insn = gen_rtx_USE (GET_MODE (current_function_ehc), 1061 current_function_ehc); 1062 insn = emit_insn_before (insn, get_first_nonparm_insn ()); 1063 1064 REG_NOTES (insn) 1065 = gen_rtx_EXPR_LIST (REG_EH_CONTEXT, current_function_ehc, 1066 REG_NOTES (insn)); 1067 } 1068 return current_function_ehc; 1069} 1070 1071/* Get a reference to the dynamic handler chain. It points to the 1072 pointer to the next element in the dynamic handler chain. It ends 1073 when there are no more elements in the dynamic handler chain, when 1074 the value is &top_elt from libgcc2.c. Immediately after the 1075 pointer, is an area suitable for setjmp/longjmp when 1076 DONT_USE_BUILTIN_SETJMP is defined, and an area suitable for 1077 __builtin_setjmp/__builtin_longjmp when DONT_USE_BUILTIN_SETJMP 1078 isn't defined. */ 1079 1080rtx 1081get_dynamic_handler_chain () 1082{ 1083 rtx ehc, dhc, result; 1084 1085 ehc = get_eh_context (); 1086 1087 /* This is the offset of dynamic_handler_chain in the eh_context struct 1088 declared in eh-common.h. If its location is change, change this offset */ 1089 dhc = plus_constant (ehc, POINTER_SIZE / BITS_PER_UNIT); 1090 1091 result = copy_to_reg (dhc); 1092 1093 /* We don't want a copy of the dcc, but rather, the single dcc. */ 1094 return gen_rtx_MEM (Pmode, result); 1095} 1096 1097/* Get a reference to the dynamic cleanup chain. It points to the 1098 pointer to the next element in the dynamic cleanup chain. 1099 Immediately after the pointer, are two Pmode variables, one for a 1100 pointer to a function that performs the cleanup action, and the 1101 second, the argument to pass to that function. */ 1102 1103rtx 1104get_dynamic_cleanup_chain () 1105{ 1106 rtx dhc, dcc, result; 1107 1108 dhc = get_dynamic_handler_chain (); 1109 dcc = plus_constant (dhc, POINTER_SIZE / BITS_PER_UNIT); 1110 1111 result = copy_to_reg (dcc); 1112 1113 /* We don't want a copy of the dcc, but rather, the single dcc. */ 1114 return gen_rtx_MEM (Pmode, result); 1115} 1116 1117#ifdef DONT_USE_BUILTIN_SETJMP 1118/* Generate code to evaluate X and jump to LABEL if the value is nonzero. 1119 LABEL is an rtx of code CODE_LABEL, in this function. */ 1120 1121static void 1122jumpif_rtx (x, label) 1123 rtx x; 1124 rtx label; 1125{ 1126 jumpif (make_tree (type_for_mode (GET_MODE (x), 0), x), label); 1127} 1128#endif 1129 1130/* Start a dynamic cleanup on the EH runtime dynamic cleanup stack. 1131 We just need to create an element for the cleanup list, and push it 1132 into the chain. 1133 1134 A dynamic cleanup is a cleanup action implied by the presence of an 1135 element on the EH runtime dynamic cleanup stack that is to be 1136 performed when an exception is thrown. The cleanup action is 1137 performed by __sjthrow when an exception is thrown. Only certain 1138 actions can be optimized into dynamic cleanup actions. For the 1139 restrictions on what actions can be performed using this routine, 1140 see expand_eh_region_start_tree. */ 1141 1142static void 1143start_dynamic_cleanup (func, arg) 1144 tree func; 1145 tree arg; 1146{ 1147 rtx dcc; 1148 rtx new_func, new_arg; 1149 rtx x, buf; 1150 int size; 1151 1152 /* We allocate enough room for a pointer to the function, and 1153 one argument. */ 1154 size = 2; 1155 1156 /* XXX, FIXME: The stack space allocated this way is too long lived, 1157 but there is no allocation routine that allocates at the level of 1158 the last binding contour. */ 1159 buf = assign_stack_local (BLKmode, 1160 GET_MODE_SIZE (Pmode)*(size+1), 1161 0); 1162 1163 buf = change_address (buf, Pmode, NULL_RTX); 1164 1165 /* Store dcc into the first word of the newly allocated buffer. */ 1166 1167 dcc = get_dynamic_cleanup_chain (); 1168 emit_move_insn (buf, dcc); 1169 1170 /* Store func and arg into the cleanup list element. */ 1171 1172 new_func = gen_rtx_MEM (Pmode, plus_constant (XEXP (buf, 0), 1173 GET_MODE_SIZE (Pmode))); 1174 new_arg = gen_rtx_MEM (Pmode, plus_constant (XEXP (buf, 0), 1175 GET_MODE_SIZE (Pmode)*2)); 1176 x = expand_expr (func, new_func, Pmode, 0); 1177 if (x != new_func) 1178 emit_move_insn (new_func, x); 1179 1180 x = expand_expr (arg, new_arg, Pmode, 0); 1181 if (x != new_arg) 1182 emit_move_insn (new_arg, x); 1183 1184 /* Update the cleanup chain. */ 1185 1186 emit_move_insn (dcc, XEXP (buf, 0)); 1187} 1188 1189/* Emit RTL to start a dynamic handler on the EH runtime dynamic 1190 handler stack. This should only be used by expand_eh_region_start 1191 or expand_eh_region_start_tree. */ 1192 1193static void 1194start_dynamic_handler () 1195{ 1196 rtx dhc, dcc; 1197 rtx x, arg, buf; 1198 int size; 1199 1200#ifndef DONT_USE_BUILTIN_SETJMP 1201 /* The number of Pmode words for the setjmp buffer, when using the 1202 builtin setjmp/longjmp, see expand_builtin, case 1203 BUILT_IN_LONGJMP. */ 1204 size = 5; 1205#else 1206#ifdef JMP_BUF_SIZE 1207 size = JMP_BUF_SIZE; 1208#else 1209 /* Should be large enough for most systems, if it is not, 1210 JMP_BUF_SIZE should be defined with the proper value. It will 1211 also tend to be larger than necessary for most systems, a more 1212 optimal port will define JMP_BUF_SIZE. */ 1213 size = FIRST_PSEUDO_REGISTER+2; 1214#endif 1215#endif 1216 /* XXX, FIXME: The stack space allocated this way is too long lived, 1217 but there is no allocation routine that allocates at the level of 1218 the last binding contour. */ 1219 arg = assign_stack_local (BLKmode, 1220 GET_MODE_SIZE (Pmode)*(size+1), 1221 0); 1222 1223 arg = change_address (arg, Pmode, NULL_RTX); 1224 1225 /* Store dhc into the first word of the newly allocated buffer. */ 1226 1227 dhc = get_dynamic_handler_chain (); 1228 dcc = gen_rtx_MEM (Pmode, plus_constant (XEXP (arg, 0), 1229 GET_MODE_SIZE (Pmode))); 1230 emit_move_insn (arg, dhc); 1231 1232 /* Zero out the start of the cleanup chain. */ 1233 emit_move_insn (dcc, const0_rtx); 1234 1235 /* The jmpbuf starts two words into the area allocated. */ 1236 buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2); 1237 1238#ifdef DONT_USE_BUILTIN_SETJMP 1239 x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1, SImode, 1, 1240 buf, Pmode); 1241 /* If we come back here for a catch, transfer control to the handler. */ 1242 jumpif_rtx (x, ehstack.top->entry->exception_handler_label); 1243#else 1244 { 1245 /* A label to continue execution for the no exception case. */ 1246 rtx noex = gen_label_rtx(); 1247 x = expand_builtin_setjmp (buf, NULL_RTX, noex, 1248 ehstack.top->entry->exception_handler_label); 1249 emit_label (noex); 1250 } 1251#endif 1252 1253 /* We are committed to this, so update the handler chain. */ 1254 1255 emit_move_insn (dhc, XEXP (arg, 0)); 1256} 1257 1258/* Start an exception handling region for the given cleanup action. 1259 All instructions emitted after this point are considered to be part 1260 of the region until expand_eh_region_end is invoked. CLEANUP is 1261 the cleanup action to perform. The return value is true if the 1262 exception region was optimized away. If that case, 1263 expand_eh_region_end does not need to be called for this cleanup, 1264 nor should it be. 1265 1266 This routine notices one particular common case in C++ code 1267 generation, and optimizes it so as to not need the exception 1268 region. It works by creating a dynamic cleanup action, instead of 1269 a using an exception region. */ 1270 1271int 1272expand_eh_region_start_tree (decl, cleanup) 1273 tree decl; 1274 tree cleanup; 1275{ 1276 /* This is the old code. */ 1277 if (! doing_eh (0)) 1278 return 0; 1279 1280 /* The optimization only applies to actions protected with 1281 terminate, and only applies if we are using the setjmp/longjmp 1282 codegen method. */ 1283 if (exceptions_via_longjmp 1284 && protect_cleanup_actions_with_terminate) 1285 { 1286 tree func, arg; 1287 tree args; 1288 1289 /* Ignore any UNSAVE_EXPR. */ 1290 if (TREE_CODE (cleanup) == UNSAVE_EXPR) 1291 cleanup = TREE_OPERAND (cleanup, 0); 1292 1293 /* Further, it only applies if the action is a call, if there 1294 are 2 arguments, and if the second argument is 2. */ 1295 1296 if (TREE_CODE (cleanup) == CALL_EXPR 1297 && (args = TREE_OPERAND (cleanup, 1)) 1298 && (func = TREE_OPERAND (cleanup, 0)) 1299 && (arg = TREE_VALUE (args)) 1300 && (args = TREE_CHAIN (args)) 1301 1302 /* is the second argument 2? */ 1303 && TREE_CODE (TREE_VALUE (args)) == INTEGER_CST 1304 && TREE_INT_CST_LOW (TREE_VALUE (args)) == 2 1305 && TREE_INT_CST_HIGH (TREE_VALUE (args)) == 0 1306 1307 /* Make sure there are no other arguments. */ 1308 && TREE_CHAIN (args) == NULL_TREE) 1309 { 1310 /* Arrange for returns and gotos to pop the entry we make on the 1311 dynamic cleanup stack. */ 1312 expand_dcc_cleanup (decl); 1313 start_dynamic_cleanup (func, arg); 1314 return 1; 1315 } 1316 } 1317 1318 expand_eh_region_start_for_decl (decl); 1319 ehstack.top->entry->finalization = cleanup; 1320 1321 return 0; 1322} 1323 1324/* Just like expand_eh_region_start, except if a cleanup action is 1325 entered on the cleanup chain, the TREE_PURPOSE of the element put 1326 on the chain is DECL. DECL should be the associated VAR_DECL, if 1327 any, otherwise it should be NULL_TREE. */ 1328 1329void 1330expand_eh_region_start_for_decl (decl) 1331 tree decl; 1332{ 1333 rtx note; 1334 1335 /* This is the old code. */ 1336 if (! doing_eh (0)) 1337 return; 1338 1339 if (exceptions_via_longjmp) 1340 { 1341 /* We need a new block to record the start and end of the 1342 dynamic handler chain. We could always do this, but we 1343 really want to permit jumping into such a block, and we want 1344 to avoid any errors or performance impact in the SJ EH code 1345 for now. */ 1346 expand_start_bindings (0); 1347 1348 /* But we don't need or want a new temporary level. */ 1349 pop_temp_slots (); 1350 1351 /* Mark this block as created by expand_eh_region_start. This 1352 is so that we can pop the block with expand_end_bindings 1353 automatically. */ 1354 mark_block_as_eh_region (); 1355 1356 /* Arrange for returns and gotos to pop the entry we make on the 1357 dynamic handler stack. */ 1358 expand_dhc_cleanup (decl); 1359 } 1360 1361 push_eh_entry (&ehstack); 1362 note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG); 1363 NOTE_BLOCK_NUMBER (note) 1364 = CODE_LABEL_NUMBER (ehstack.top->entry->exception_handler_label); 1365 if (exceptions_via_longjmp) 1366 start_dynamic_handler (); 1367} 1368 1369/* Start an exception handling region. All instructions emitted after 1370 this point are considered to be part of the region until 1371 expand_eh_region_end is invoked. */ 1372 1373void 1374expand_eh_region_start () 1375{ 1376 expand_eh_region_start_for_decl (NULL_TREE); 1377} 1378 1379/* End an exception handling region. The information about the region 1380 is found on the top of ehstack. 1381 1382 HANDLER is either the cleanup for the exception region, or if we're 1383 marking the end of a try block, HANDLER is integer_zero_node. 1384 1385 HANDLER will be transformed to rtl when expand_leftover_cleanups 1386 is invoked. */ 1387 1388void 1389expand_eh_region_end (handler) 1390 tree handler; 1391{ 1392 struct eh_entry *entry; 1393 rtx note; 1394 1395 if (! doing_eh (0)) 1396 return; 1397 1398 entry = pop_eh_entry (&ehstack); 1399 1400 note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END); 1401 NOTE_BLOCK_NUMBER (note) 1402 = CODE_LABEL_NUMBER (entry->exception_handler_label); 1403 if (exceptions_via_longjmp == 0 1404 /* We share outer_context between regions; only emit it once. */ 1405 && INSN_UID (entry->outer_context) == 0) 1406 { 1407 rtx label; 1408 1409 label = gen_label_rtx (); 1410 emit_jump (label); 1411 1412 /* Emit a label marking the end of this exception region that 1413 is used for rethrowing into the outer context. */ 1414 emit_label (entry->outer_context); 1415 expand_internal_throw (); 1416 1417 emit_label (label); 1418 } 1419 1420 entry->finalization = handler; 1421 1422 /* create region entry in final exception table */ 1423 new_eh_region_entry (NOTE_BLOCK_NUMBER (note)); 1424 1425 enqueue_eh_entry (&ehqueue, entry); 1426 1427 /* If we have already started ending the bindings, don't recurse. 1428 This only happens when exceptions_via_longjmp is true. */ 1429 if (is_eh_region ()) 1430 { 1431 /* Because we don't need or want a new temporary level and 1432 because we didn't create one in expand_eh_region_start, 1433 create a fake one now to avoid removing one in 1434 expand_end_bindings. */ 1435 push_temp_slots (); 1436 1437 mark_block_as_not_eh_region (); 1438 1439 /* Maybe do this to prevent jumping in and so on... */ 1440 expand_end_bindings (NULL_TREE, 0, 0); 1441 } 1442} 1443 1444/* End the EH region for a goto fixup. We only need them in the region-based 1445 EH scheme. */ 1446 1447void 1448expand_fixup_region_start () 1449{ 1450 if (! doing_eh (0) || exceptions_via_longjmp) 1451 return; 1452 1453 expand_eh_region_start (); 1454} 1455 1456/* End the EH region for a goto fixup. CLEANUP is the cleanup we just 1457 expanded; to avoid running it twice if it throws, we look through the 1458 ehqueue for a matching region and rethrow from its outer_context. */ 1459 1460void 1461expand_fixup_region_end (cleanup) 1462 tree cleanup; 1463{ 1464 struct eh_node *node; 1465 int dont_issue; 1466 1467 if (! doing_eh (0) || exceptions_via_longjmp) 1468 return; 1469 1470 for (node = ehstack.top; node && node->entry->finalization != cleanup; ) 1471 node = node->chain; 1472 if (node == 0) 1473 for (node = ehqueue.head; node && node->entry->finalization != cleanup; ) 1474 node = node->chain; 1475 if (node == 0) 1476 abort (); 1477 1478 /* If the outer context label has not been issued yet, we don't want 1479 to issue it as a part of this region, unless this is the 1480 correct region for the outer context. If we did, then the label for 1481 the outer context will be WITHIN the begin/end labels, 1482 and we could get an infinte loop when it tried to rethrow, or just 1483 generally incorrect execution following a throw. */ 1484 1485 dont_issue = ((INSN_UID (node->entry->outer_context) == 0) 1486 && (ehstack.top->entry != node->entry)); 1487 1488 ehstack.top->entry->outer_context = node->entry->outer_context; 1489 1490 /* Since we are rethrowing to the OUTER region, we know we don't need 1491 a jump around sequence for this region, so we'll pretend the outer 1492 context label has been issued by setting INSN_UID to 1, then clearing 1493 it again afterwards. */ 1494 1495 if (dont_issue) 1496 INSN_UID (node->entry->outer_context) = 1; 1497 1498 /* Just rethrow. size_zero_node is just a NOP. */ 1499 expand_eh_region_end (size_zero_node); 1500 1501 if (dont_issue) 1502 INSN_UID (node->entry->outer_context) = 0; 1503} 1504 1505/* If we are using the setjmp/longjmp EH codegen method, we emit a 1506 call to __sjthrow. 1507 1508 Otherwise, we emit a call to __throw and note that we threw 1509 something, so we know we need to generate the necessary code for 1510 __throw. 1511 1512 Before invoking throw, the __eh_pc variable must have been set up 1513 to contain the PC being thrown from. This address is used by 1514 __throw to determine which exception region (if any) is 1515 responsible for handling the exception. */ 1516 1517void 1518emit_throw () 1519{ 1520 if (exceptions_via_longjmp) 1521 { 1522 emit_library_call (sjthrow_libfunc, 0, VOIDmode, 0); 1523 } 1524 else 1525 { 1526#ifdef JUMP_TO_THROW 1527 emit_indirect_jump (throw_libfunc); 1528#else 1529 emit_library_call (throw_libfunc, 0, VOIDmode, 0); 1530#endif 1531 } 1532 emit_barrier (); 1533} 1534 1535/* Throw the current exception. If appropriate, this is done by jumping 1536 to the next handler. */ 1537 1538void 1539expand_internal_throw () 1540{ 1541 emit_throw (); 1542} 1543 1544/* Called from expand_exception_blocks and expand_end_catch_block to 1545 emit any pending handlers/cleanups queued from expand_eh_region_end. */ 1546 1547void 1548expand_leftover_cleanups () 1549{ 1550 struct eh_entry *entry; 1551 1552 while ((entry = dequeue_eh_entry (&ehqueue)) != 0) 1553 { 1554 rtx prev; 1555 1556 /* A leftover try block. Shouldn't be one here. */ 1557 if (entry->finalization == integer_zero_node) 1558 abort (); 1559 1560 /* Output the label for the start of the exception handler. */ 1561 1562 receive_exception_label (entry->exception_handler_label); 1563 1564 /* register a handler for this cleanup region */ 1565 add_new_handler ( 1566 find_func_region (CODE_LABEL_NUMBER (entry->exception_handler_label)), 1567 get_new_handler (entry->exception_handler_label, NULL)); 1568 1569 /* And now generate the insns for the handler. */ 1570 expand_expr (entry->finalization, const0_rtx, VOIDmode, 0); 1571 1572 prev = get_last_insn (); 1573 if (prev == NULL || GET_CODE (prev) != BARRIER) 1574 /* Emit code to throw to the outer context if we fall off 1575 the end of the handler. */ 1576 expand_rethrow (entry->outer_context); 1577 1578 do_pending_stack_adjust (); 1579 free (entry); 1580 } 1581} 1582 1583/* Called at the start of a block of try statements. */ 1584void 1585expand_start_try_stmts () 1586{ 1587 if (! doing_eh (1)) 1588 return; 1589 1590 expand_eh_region_start (); 1591} 1592 1593/* Called to begin a catch clause. The parameter is the object which 1594 will be passed to the runtime type check routine. */ 1595void 1596start_catch_handler (rtime) 1597 tree rtime; 1598{ 1599 rtx handler_label; 1600 int insn_region_num; 1601 int eh_region_entry; 1602 1603 if (! doing_eh (1)) 1604 return; 1605 1606 handler_label = catchstack.top->entry->exception_handler_label; 1607 insn_region_num = CODE_LABEL_NUMBER (handler_label); 1608 eh_region_entry = find_func_region (insn_region_num); 1609 1610 /* If we've already issued this label, pick a new one */ 1611 if (catchstack.top->entry->label_used) 1612 handler_label = gen_exception_label (); 1613 else 1614 catchstack.top->entry->label_used = 1; 1615 1616 receive_exception_label (handler_label); 1617 1618 add_new_handler (eh_region_entry, get_new_handler (handler_label, rtime)); 1619} 1620 1621/* Generate RTL for the start of a group of catch clauses. 1622 1623 It is responsible for starting a new instruction sequence for the 1624 instructions in the catch block, and expanding the handlers for the 1625 internally-generated exception regions nested within the try block 1626 corresponding to this catch block. */ 1627 1628void 1629expand_start_all_catch () 1630{ 1631 struct eh_entry *entry; 1632 tree label; 1633 rtx outer_context; 1634 1635 if (! doing_eh (1)) 1636 return; 1637 1638 outer_context = ehstack.top->entry->outer_context; 1639 1640 /* End the try block. */ 1641 expand_eh_region_end (integer_zero_node); 1642 1643 emit_line_note (input_filename, lineno); 1644 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); 1645 1646 /* The label for the exception handling block that we will save. 1647 This is Lresume in the documentation. */ 1648 expand_label (label); 1649 1650 /* Push the label that points to where normal flow is resumed onto 1651 the top of the label stack. */ 1652 push_label_entry (&caught_return_label_stack, NULL_RTX, label); 1653 1654 /* Start a new sequence for all the catch blocks. We will add this 1655 to the global sequence catch_clauses when we have completed all 1656 the handlers in this handler-seq. */ 1657 start_sequence (); 1658 1659 entry = dequeue_eh_entry (&ehqueue); 1660 for ( ; entry->finalization != integer_zero_node; 1661 entry = dequeue_eh_entry (&ehqueue)) 1662 { 1663 rtx prev; 1664 1665 /* Emit the label for the cleanup handler for this region, and 1666 expand the code for the handler. 1667 1668 Note that a catch region is handled as a side-effect here; 1669 for a try block, entry->finalization will contain 1670 integer_zero_node, so no code will be generated in the 1671 expand_expr call below. But, the label for the handler will 1672 still be emitted, so any code emitted after this point will 1673 end up being the handler. */ 1674 1675 receive_exception_label (entry->exception_handler_label); 1676 1677 /* register a handler for this cleanup region */ 1678 add_new_handler ( 1679 find_func_region (CODE_LABEL_NUMBER (entry->exception_handler_label)), 1680 get_new_handler (entry->exception_handler_label, NULL)); 1681 1682 /* And now generate the insns for the cleanup handler. */ 1683 expand_expr (entry->finalization, const0_rtx, VOIDmode, 0); 1684 1685 prev = get_last_insn (); 1686 if (prev == NULL || GET_CODE (prev) != BARRIER) 1687 /* Code to throw out to outer context when we fall off end 1688 of the handler. We can't do this here for catch blocks, 1689 so it's done in expand_end_all_catch instead. */ 1690 expand_rethrow (entry->outer_context); 1691 1692 do_pending_stack_adjust (); 1693 free (entry); 1694 } 1695 1696 /* At this point, all the cleanups are done, and the ehqueue now has 1697 the current exception region at its head. We dequeue it, and put it 1698 on the catch stack. */ 1699 1700 push_entry (&catchstack, entry); 1701 1702 /* If we are not doing setjmp/longjmp EH, because we are reordered 1703 out of line, we arrange to rethrow in the outer context. We need to 1704 do this because we are not physically within the region, if any, that 1705 logically contains this catch block. */ 1706 if (! exceptions_via_longjmp) 1707 { 1708 expand_eh_region_start (); 1709 ehstack.top->entry->outer_context = outer_context; 1710 } 1711 1712 /* We also have to start the handler if we aren't using the new model. */ 1713 if (! flag_new_exceptions) 1714 start_catch_handler (NULL); 1715} 1716 1717/* Finish up the catch block. At this point all the insns for the 1718 catch clauses have already been generated, so we only have to add 1719 them to the catch_clauses list. We also want to make sure that if 1720 we fall off the end of the catch clauses that we rethrow to the 1721 outer EH region. */ 1722 1723void 1724expand_end_all_catch () 1725{ 1726 rtx new_catch_clause, outer_context = NULL_RTX; 1727 struct eh_entry *entry; 1728 1729 if (! doing_eh (1)) 1730 return; 1731 1732 /* Dequeue the current catch clause region. */ 1733 entry = pop_eh_entry (&catchstack); 1734 free (entry); 1735 1736 if (! exceptions_via_longjmp) 1737 { 1738 outer_context = ehstack.top->entry->outer_context; 1739 1740 /* Finish the rethrow region. size_zero_node is just a NOP. */ 1741 expand_eh_region_end (size_zero_node); 1742 } 1743 1744 /* Code to throw out to outer context, if we fall off end of catch 1745 handlers. This is rethrow (Lresume, same id, same obj) in the 1746 documentation. We use Lresume because we know that it will throw 1747 to the correct context. 1748 1749 In other words, if the catch handler doesn't exit or return, we 1750 do a "throw" (using the address of Lresume as the point being 1751 thrown from) so that the outer EH region can then try to process 1752 the exception. */ 1753 expand_rethrow (outer_context); 1754 1755 /* Now we have the complete catch sequence. */ 1756 new_catch_clause = get_insns (); 1757 end_sequence (); 1758 1759 /* This level of catch blocks is done, so set up the successful 1760 catch jump label for the next layer of catch blocks. */ 1761 pop_label_entry (&caught_return_label_stack); 1762 pop_label_entry (&outer_context_label_stack); 1763 1764 /* Add the new sequence of catches to the main one for this function. */ 1765 push_to_sequence (catch_clauses); 1766 emit_insns (new_catch_clause); 1767 catch_clauses = get_insns (); 1768 end_sequence (); 1769 1770 /* Here we fall through into the continuation code. */ 1771} 1772 1773/* Rethrow from the outer context LABEL. */ 1774 1775static void 1776expand_rethrow (label) 1777 rtx label; 1778{ 1779 if (exceptions_via_longjmp) 1780 emit_throw (); 1781 else 1782 emit_jump (label); 1783} 1784 1785/* End all the pending exception regions on protect_list. The handlers 1786 will be emitted when expand_leftover_cleanups is invoked. */ 1787 1788void 1789end_protect_partials () 1790{ 1791 while (protect_list) 1792 { 1793 expand_eh_region_end (TREE_VALUE (protect_list)); 1794 protect_list = TREE_CHAIN (protect_list); 1795 } 1796} 1797 1798/* Arrange for __terminate to be called if there is an unhandled throw 1799 from within E. */ 1800 1801tree 1802protect_with_terminate (e) 1803 tree e; 1804{ 1805 /* We only need to do this when using setjmp/longjmp EH and the 1806 language requires it, as otherwise we protect all of the handlers 1807 at once, if we need to. */ 1808 if (exceptions_via_longjmp && protect_cleanup_actions_with_terminate) 1809 { 1810 tree handler, result; 1811 1812 /* All cleanups must be on the function_obstack. */ 1813 push_obstacks_nochange (); 1814 resume_temporary_allocation (); 1815 1816 handler = make_node (RTL_EXPR); 1817 TREE_TYPE (handler) = void_type_node; 1818 RTL_EXPR_RTL (handler) = const0_rtx; 1819 TREE_SIDE_EFFECTS (handler) = 1; 1820 start_sequence_for_rtl_expr (handler); 1821 1822 emit_library_call (terminate_libfunc, 0, VOIDmode, 0); 1823 emit_barrier (); 1824 1825 RTL_EXPR_SEQUENCE (handler) = get_insns (); 1826 end_sequence (); 1827 1828 result = build (TRY_CATCH_EXPR, TREE_TYPE (e), e, handler); 1829 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e); 1830 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e); 1831 TREE_READONLY (result) = TREE_READONLY (e); 1832 1833 pop_obstacks (); 1834 1835 e = result; 1836 } 1837 1838 return e; 1839} 1840 1841/* The exception table that we build that is used for looking up and 1842 dispatching exceptions, the current number of entries, and its 1843 maximum size before we have to extend it. 1844 1845 The number in eh_table is the code label number of the exception 1846 handler for the region. This is added by add_eh_table_entry and 1847 used by output_exception_table_entry. */ 1848 1849static int *eh_table = NULL; 1850static int eh_table_size = 0; 1851static int eh_table_max_size = 0; 1852 1853/* Note the need for an exception table entry for region N. If we 1854 don't need to output an explicit exception table, avoid all of the 1855 extra work. 1856 1857 Called from final_scan_insn when a NOTE_INSN_EH_REGION_BEG is seen. 1858 (Or NOTE_INSN_EH_REGION_END sometimes) 1859 N is the NOTE_BLOCK_NUMBER of the note, which comes from the code 1860 label number of the exception handler for the region. */ 1861 1862void 1863add_eh_table_entry (n) 1864 int n; 1865{ 1866#ifndef OMIT_EH_TABLE 1867 if (eh_table_size >= eh_table_max_size) 1868 { 1869 if (eh_table) 1870 { 1871 eh_table_max_size += eh_table_max_size>>1; 1872 1873 if (eh_table_max_size < 0) 1874 abort (); 1875 1876 eh_table = (int *) xrealloc (eh_table, 1877 eh_table_max_size * sizeof (int)); 1878 } 1879 else 1880 { 1881 eh_table_max_size = 252; 1882 eh_table = (int *) xmalloc (eh_table_max_size * sizeof (int)); 1883 } 1884 } 1885 eh_table[eh_table_size++] = n; 1886#endif 1887} 1888 1889/* Return a non-zero value if we need to output an exception table. 1890 1891 On some platforms, we don't have to output a table explicitly. 1892 This routine doesn't mean we don't have one. */ 1893 1894int 1895exception_table_p () 1896{ 1897 if (eh_table) 1898 return 1; 1899 1900 return 0; 1901} 1902 1903/* Output the entry of the exception table corresponding to the 1904 exception region numbered N to file FILE. 1905 1906 N is the code label number corresponding to the handler of the 1907 region. */ 1908 1909static void 1910output_exception_table_entry (file, n) 1911 FILE *file; 1912 int n; 1913{ 1914 char buf[256]; 1915 rtx sym; 1916 struct handler_info *handler; 1917 1918 handler = get_first_handler (n); 1919 1920 for ( ; handler != NULL; handler = handler->next) 1921 { 1922 ASM_GENERATE_INTERNAL_LABEL (buf, "LEHB", n); 1923 sym = gen_rtx_SYMBOL_REF (Pmode, buf); 1924 assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1); 1925 1926 ASM_GENERATE_INTERNAL_LABEL (buf, "LEHE", n); 1927 sym = gen_rtx_SYMBOL_REF (Pmode, buf); 1928 assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1); 1929 1930 assemble_integer (handler->handler_label, 1931 POINTER_SIZE / BITS_PER_UNIT, 1); 1932 1933 if (flag_new_exceptions) 1934 { 1935 if (handler->type_info == NULL) 1936 assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); 1937 else 1938 if (handler->type_info == CATCH_ALL_TYPE) 1939 assemble_integer (GEN_INT (CATCH_ALL_TYPE), 1940 POINTER_SIZE / BITS_PER_UNIT, 1); 1941 else 1942 output_constant ((tree)(handler->type_info), 1943 POINTER_SIZE / BITS_PER_UNIT); 1944 } 1945 putc ('\n', file); /* blank line */ 1946 } 1947} 1948 1949/* Output the exception table if we have and need one. */ 1950 1951static short language_code = 0; 1952static short version_code = 0; 1953 1954/* This routine will set the language code for exceptions. */ 1955void set_exception_lang_code (code) 1956 short code; 1957{ 1958 language_code = code; 1959} 1960 1961/* This routine will set the language version code for exceptions. */ 1962void set_exception_version_code (code) 1963 short code; 1964{ 1965 version_code = code; 1966} 1967 1968 1969void 1970output_exception_table () 1971{ 1972 int i; 1973 extern FILE *asm_out_file; 1974 1975 if (! doing_eh (0) || ! eh_table) 1976 return; 1977 1978 exception_section (); 1979 1980 /* Beginning marker for table. */ 1981 assemble_align (GET_MODE_ALIGNMENT (ptr_mode)); 1982 assemble_label ("__EXCEPTION_TABLE__"); 1983 1984 if (flag_new_exceptions) 1985 { 1986 assemble_integer (GEN_INT (NEW_EH_RUNTIME), 1987 POINTER_SIZE / BITS_PER_UNIT, 1); 1988 assemble_integer (GEN_INT (language_code), 2 , 1); 1989 assemble_integer (GEN_INT (version_code), 2 , 1); 1990 1991 /* Add enough padding to make sure table aligns on a pointer boundry. */ 1992 i = GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT - 4; 1993 for ( ; i < 0; i = i + GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT) 1994 ; 1995 if (i != 0) 1996 assemble_integer (const0_rtx, i , 1); 1997 } 1998 1999 for (i = 0; i < eh_table_size; ++i) 2000 output_exception_table_entry (asm_out_file, eh_table[i]); 2001 2002 free (eh_table); 2003 clear_function_eh_region (); 2004 2005 /* Ending marker for table. */ 2006 assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); 2007 2008 /* for binary compatability, the old __throw checked the second 2009 position for a -1, so we should output at least 2 -1's */ 2010 if (! flag_new_exceptions) 2011 assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); 2012 2013 putc ('\n', asm_out_file); /* blank line */ 2014} 2015 2016/* Emit code to get EH context. 2017 2018 We have to scan thru the code to find possible EH context registers. 2019 Inlined functions may use it too, and thus we'll have to be able 2020 to change them too. 2021 2022 This is done only if using exceptions_via_longjmp. */ 2023 2024void 2025emit_eh_context () 2026{ 2027 rtx insn; 2028 rtx ehc = 0; 2029 2030 if (! doing_eh (0)) 2031 return; 2032 2033 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 2034 if (GET_CODE (insn) == INSN 2035 && GET_CODE (PATTERN (insn)) == USE) 2036 { 2037 rtx reg = find_reg_note (insn, REG_EH_CONTEXT, 0); 2038 if (reg) 2039 { 2040 rtx insns; 2041 2042 start_sequence (); 2043 2044 /* If this is the first use insn, emit the call here. This 2045 will always be at the top of our function, because if 2046 expand_inline_function notices a REG_EH_CONTEXT note, it 2047 adds a use insn to this function as well. */ 2048 if (ehc == 0) 2049 ehc = call_get_eh_context (); 2050 2051 emit_move_insn (XEXP (reg, 0), ehc); 2052 insns = get_insns (); 2053 end_sequence (); 2054 2055 emit_insns_before (insns, insn); 2056 } 2057 } 2058} 2059 2060/* Scan the current insns and build a list of handler labels. The 2061 resulting list is placed in the global variable exception_handler_labels. 2062 2063 It is called after the last exception handling region is added to 2064 the current function (when the rtl is almost all built for the 2065 current function) and before the jump optimization pass. */ 2066 2067void 2068find_exception_handler_labels () 2069{ 2070 rtx insn; 2071 2072 exception_handler_labels = NULL_RTX; 2073 2074 /* If we aren't doing exception handling, there isn't much to check. */ 2075 if (! doing_eh (0)) 2076 return; 2077 2078 /* For each start of a region, add its label to the list. */ 2079 2080 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 2081 { 2082 struct handler_info* ptr; 2083 if (GET_CODE (insn) == NOTE 2084 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) 2085 { 2086 ptr = get_first_handler (NOTE_BLOCK_NUMBER (insn)); 2087 for ( ; ptr; ptr = ptr->next) 2088 { 2089 /* make sure label isn't in the list already */ 2090 rtx x; 2091 for (x = exception_handler_labels; x; x = XEXP (x, 1)) 2092 if (XEXP (x, 0) == ptr->handler_label) 2093 break; 2094 if (! x) 2095 exception_handler_labels = gen_rtx_EXPR_LIST (VOIDmode, 2096 ptr->handler_label, exception_handler_labels); 2097 } 2098 } 2099 } 2100} 2101 2102/* Return a value of 1 if the parameter label number is an exception handler 2103 label. Return 0 otherwise. */ 2104 2105int 2106is_exception_handler_label (lab) 2107 int lab; 2108{ 2109 rtx x; 2110 for (x = exception_handler_labels ; x ; x = XEXP (x, 1)) 2111 if (lab == CODE_LABEL_NUMBER (XEXP (x, 0))) 2112 return 1; 2113 return 0; 2114} 2115 2116/* Perform sanity checking on the exception_handler_labels list. 2117 2118 Can be called after find_exception_handler_labels is called to 2119 build the list of exception handlers for the current function and 2120 before we finish processing the current function. */ 2121 2122void 2123check_exception_handler_labels () 2124{ 2125 rtx insn, insn2; 2126 2127 /* If we aren't doing exception handling, there isn't much to check. */ 2128 if (! doing_eh (0)) 2129 return; 2130 2131 /* Make sure there is no more than 1 copy of a label */ 2132 for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1)) 2133 { 2134 int count = 0; 2135 for (insn2 = exception_handler_labels; insn2; insn2 = XEXP (insn2, 1)) 2136 if (XEXP (insn, 0) == XEXP (insn2, 0)) 2137 count++; 2138 if (count != 1) 2139 warning ("Counted %d copies of EH region %d in list.\n", count, 2140 CODE_LABEL_NUMBER (insn)); 2141 } 2142 2143} 2144 2145/* This group of functions initializes the exception handling data 2146 structures at the start of the compilation, initializes the data 2147 structures at the start of a function, and saves and restores the 2148 exception handling data structures for the start/end of a nested 2149 function. */ 2150 2151/* Toplevel initialization for EH things. */ 2152 2153void 2154init_eh () 2155{ 2156} 2157 2158/* Initialize the per-function EH information. */ 2159 2160void 2161init_eh_for_function () 2162{ 2163 ehstack.top = 0; 2164 catchstack.top = 0; 2165 ehqueue.head = ehqueue.tail = 0; 2166 catch_clauses = NULL_RTX; 2167 false_label_stack = 0; 2168 caught_return_label_stack = 0; 2169 protect_list = NULL_TREE; 2170 current_function_ehc = NULL_RTX; 2171} 2172 2173/* Save some of the per-function EH info into the save area denoted by 2174 P. 2175 2176 This is currently called from save_stmt_status. */ 2177 2178void 2179save_eh_status (p) 2180 struct function *p; 2181{ 2182 if (p == NULL) 2183 abort (); 2184 2185 p->ehstack = ehstack; 2186 p->catchstack = catchstack; 2187 p->ehqueue = ehqueue; 2188 p->catch_clauses = catch_clauses; 2189 p->false_label_stack = false_label_stack; 2190 p->caught_return_label_stack = caught_return_label_stack; 2191 p->protect_list = protect_list; 2192 p->ehc = current_function_ehc; 2193 2194 init_eh_for_function (); 2195} 2196 2197/* Restore the per-function EH info saved into the area denoted by P. 2198 2199 This is currently called from restore_stmt_status. */ 2200 2201void 2202restore_eh_status (p) 2203 struct function *p; 2204{ 2205 if (p == NULL) 2206 abort (); 2207 2208 protect_list = p->protect_list; 2209 caught_return_label_stack = p->caught_return_label_stack; 2210 false_label_stack = p->false_label_stack; 2211 catch_clauses = p->catch_clauses; 2212 ehqueue = p->ehqueue; 2213 ehstack = p->ehstack; 2214 catchstack = p->catchstack; 2215 current_function_ehc = p->ehc; 2216} 2217 2218/* This section is for the exception handling specific optimization 2219 pass. First are the internal routines, and then the main 2220 optimization pass. */ 2221 2222/* Determine if the given INSN can throw an exception. */ 2223 2224static int 2225can_throw (insn) 2226 rtx insn; 2227{ 2228 /* Calls can always potentially throw exceptions. */ 2229 if (GET_CODE (insn) == CALL_INSN) 2230 return 1; 2231 2232 if (asynchronous_exceptions) 2233 { 2234 /* If we wanted asynchronous exceptions, then everything but NOTEs 2235 and CODE_LABELs could throw. */ 2236 if (GET_CODE (insn) != NOTE && GET_CODE (insn) != CODE_LABEL) 2237 return 1; 2238 } 2239 2240 return 0; 2241} 2242 2243/* Scan a exception region looking for the matching end and then 2244 remove it if possible. INSN is the start of the region, N is the 2245 region number, and DELETE_OUTER is to note if anything in this 2246 region can throw. 2247 2248 Regions are removed if they cannot possibly catch an exception. 2249 This is determined by invoking can_throw on each insn within the 2250 region; if can_throw returns true for any of the instructions, the 2251 region can catch an exception, since there is an insn within the 2252 region that is capable of throwing an exception. 2253 2254 Returns the NOTE_INSN_EH_REGION_END corresponding to this region, or 2255 calls abort if it can't find one. 2256 2257 Can abort if INSN is not a NOTE_INSN_EH_REGION_BEGIN, or if N doesn't 2258 correspond to the region number, or if DELETE_OUTER is NULL. */ 2259 2260static rtx 2261scan_region (insn, n, delete_outer) 2262 rtx insn; 2263 int n; 2264 int *delete_outer; 2265{ 2266 rtx start = insn; 2267 2268 /* Assume we can delete the region. */ 2269 int delete = 1; 2270 2271 if (insn == NULL_RTX 2272 || GET_CODE (insn) != NOTE 2273 || NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG 2274 || NOTE_BLOCK_NUMBER (insn) != n 2275 || delete_outer == NULL) 2276 abort (); 2277 2278 insn = NEXT_INSN (insn); 2279 2280 /* Look for the matching end. */ 2281 while (! (GET_CODE (insn) == NOTE 2282 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)) 2283 { 2284 /* If anything can throw, we can't remove the region. */ 2285 if (delete && can_throw (insn)) 2286 { 2287 delete = 0; 2288 } 2289 2290 /* Watch out for and handle nested regions. */ 2291 if (GET_CODE (insn) == NOTE 2292 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) 2293 { 2294 insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &delete); 2295 } 2296 2297 insn = NEXT_INSN (insn); 2298 } 2299 2300 /* The _BEG/_END NOTEs must match and nest. */ 2301 if (NOTE_BLOCK_NUMBER (insn) != n) 2302 abort (); 2303 2304 /* If anything in this exception region can throw, we can throw. */ 2305 if (! delete) 2306 *delete_outer = 0; 2307 else 2308 { 2309 /* Delete the start and end of the region. */ 2310 delete_insn (start); 2311 delete_insn (insn); 2312 2313/* We no longer removed labels here, since flow will now remove any 2314 handler which cannot be called any more. */ 2315 2316#if 0 2317 /* Only do this part if we have built the exception handler 2318 labels. */ 2319 if (exception_handler_labels) 2320 { 2321 rtx x, *prev = &exception_handler_labels; 2322 2323 /* Find it in the list of handlers. */ 2324 for (x = exception_handler_labels; x; x = XEXP (x, 1)) 2325 { 2326 rtx label = XEXP (x, 0); 2327 if (CODE_LABEL_NUMBER (label) == n) 2328 { 2329 /* If we are the last reference to the handler, 2330 delete it. */ 2331 if (--LABEL_NUSES (label) == 0) 2332 delete_insn (label); 2333 2334 if (optimize) 2335 { 2336 /* Remove it from the list of exception handler 2337 labels, if we are optimizing. If we are not, then 2338 leave it in the list, as we are not really going to 2339 remove the region. */ 2340 *prev = XEXP (x, 1); 2341 XEXP (x, 1) = 0; 2342 XEXP (x, 0) = 0; 2343 } 2344 2345 break; 2346 } 2347 prev = &XEXP (x, 1); 2348 } 2349 } 2350#endif 2351 } 2352 return insn; 2353} 2354 2355/* Perform various interesting optimizations for exception handling 2356 code. 2357 2358 We look for empty exception regions and make them go (away). The 2359 jump optimization code will remove the handler if nothing else uses 2360 it. */ 2361 2362void 2363exception_optimize () 2364{ 2365 rtx insn; 2366 int n; 2367 2368 /* Remove empty regions. */ 2369 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 2370 { 2371 if (GET_CODE (insn) == NOTE 2372 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) 2373 { 2374 /* Since scan_region will return the NOTE_INSN_EH_REGION_END 2375 insn, we will indirectly skip through all the insns 2376 inbetween. We are also guaranteed that the value of insn 2377 returned will be valid, as otherwise scan_region won't 2378 return. */ 2379 insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &n); 2380 } 2381 } 2382} 2383 2384/* Various hooks for the DWARF 2 __throw routine. */ 2385 2386/* Do any necessary initialization to access arbitrary stack frames. 2387 On the SPARC, this means flushing the register windows. */ 2388 2389void 2390expand_builtin_unwind_init () 2391{ 2392 /* Set this so all the registers get saved in our frame; we need to be 2393 able to copy the saved values for any registers from frames we unwind. */ 2394 current_function_has_nonlocal_label = 1; 2395 2396#ifdef SETUP_FRAME_ADDRESSES 2397 SETUP_FRAME_ADDRESSES (); 2398#endif 2399} 2400 2401/* Given a value extracted from the return address register or stack slot, 2402 return the actual address encoded in that value. */ 2403 2404rtx 2405expand_builtin_extract_return_addr (addr_tree) 2406 tree addr_tree; 2407{ 2408 rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0); 2409 return eh_outer_context (addr); 2410} 2411 2412/* Given an actual address in addr_tree, do any necessary encoding 2413 and return the value to be stored in the return address register or 2414 stack slot so the epilogue will return to that address. */ 2415 2416rtx 2417expand_builtin_frob_return_addr (addr_tree) 2418 tree addr_tree; 2419{ 2420 rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0); 2421#ifdef RETURN_ADDR_OFFSET 2422 addr = plus_constant (addr, -RETURN_ADDR_OFFSET); 2423#endif 2424 return addr; 2425} 2426 2427/* Given an actual address in addr_tree, set the return address register up 2428 so the epilogue will return to that address. If the return address is 2429 not in a register, do nothing. */ 2430 2431void 2432expand_builtin_set_return_addr_reg (addr_tree) 2433 tree addr_tree; 2434{ 2435 rtx tmp; 2436 rtx ra = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS, 2437 0, hard_frame_pointer_rtx); 2438 2439 if (GET_CODE (ra) != REG || REGNO (ra) >= FIRST_PSEUDO_REGISTER) 2440 return; 2441 2442 tmp = force_operand (expand_builtin_frob_return_addr (addr_tree), ra); 2443 if (tmp != ra) 2444 emit_move_insn (ra, tmp); 2445} 2446 2447/* Choose two registers for communication between the main body of 2448 __throw and the stub for adjusting the stack pointer. The first register 2449 is used to pass the address of the exception handler; the second register 2450 is used to pass the stack pointer offset. 2451 2452 For register 1 we use the return value register for a void *. 2453 For register 2 we use the static chain register if it exists and is 2454 different from register 1, otherwise some arbitrary call-clobbered 2455 register. */ 2456 2457static void 2458eh_regs (r1, r2, outgoing) 2459 rtx *r1, *r2; 2460 int outgoing; 2461{ 2462 rtx reg1, reg2; 2463 2464#ifdef FUNCTION_OUTGOING_VALUE 2465 if (outgoing) 2466 reg1 = FUNCTION_OUTGOING_VALUE (build_pointer_type (void_type_node), 2467 current_function_decl); 2468 else 2469#endif 2470 reg1 = FUNCTION_VALUE (build_pointer_type (void_type_node), 2471 current_function_decl); 2472 2473#ifdef STATIC_CHAIN_REGNUM 2474 if (outgoing) 2475 reg2 = static_chain_incoming_rtx; 2476 else 2477 reg2 = static_chain_rtx; 2478 if (REGNO (reg2) == REGNO (reg1)) 2479#endif /* STATIC_CHAIN_REGNUM */ 2480 reg2 = NULL_RTX; 2481 2482 if (reg2 == NULL_RTX) 2483 { 2484 int i; 2485 for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) 2486 if (call_used_regs[i] && ! fixed_regs[i] && i != REGNO (reg1)) 2487 { 2488 reg2 = gen_rtx_REG (Pmode, i); 2489 break; 2490 } 2491 2492 if (reg2 == NULL_RTX) 2493 abort (); 2494 } 2495 2496 *r1 = reg1; 2497 *r2 = reg2; 2498} 2499 2500 2501/* Retrieve the register which contains the pointer to the eh_context 2502 structure set the __throw. */ 2503 2504rtx 2505get_reg_for_handler () 2506{ 2507 rtx reg1; 2508 reg1 = FUNCTION_VALUE (build_pointer_type (void_type_node), 2509 current_function_decl); 2510 return reg1; 2511} 2512 2513 2514/* Emit inside of __throw a stub which adjusts the stack pointer and jumps 2515 to the exception handler. __throw will set up the necessary values 2516 and then return to the stub. */ 2517 2518rtx 2519expand_builtin_eh_stub_old () 2520{ 2521 rtx stub_start = gen_label_rtx (); 2522 rtx after_stub = gen_label_rtx (); 2523 rtx handler, offset; 2524 2525 emit_jump (after_stub); 2526 emit_label (stub_start); 2527 2528 eh_regs (&handler, &offset, 0); 2529 2530 adjust_stack (offset); 2531 emit_indirect_jump (handler); 2532 emit_label (after_stub); 2533 return gen_rtx_LABEL_REF (Pmode, stub_start); 2534} 2535 2536rtx 2537expand_builtin_eh_stub () 2538{ 2539 rtx stub_start = gen_label_rtx (); 2540 rtx after_stub = gen_label_rtx (); 2541 rtx handler, offset; 2542 rtx temp; 2543 2544 emit_jump (after_stub); 2545 emit_label (stub_start); 2546 2547 eh_regs (&handler, &offset, 0); 2548 2549 adjust_stack (offset); 2550 2551 /* Handler is in fact a pointer to the _eh_context structure, we need 2552 to pick out the handler field (first element), and jump to there, 2553 leaving the pointer to _eh_conext in the same hardware register. */ 2554 2555 temp = gen_rtx_MEM (Pmode, handler); 2556 MEM_IN_STRUCT_P (temp) = 1; 2557 RTX_UNCHANGING_P (temp) = 1; 2558 emit_move_insn (offset, temp); 2559 emit_insn (gen_rtx_USE (Pmode, handler)); 2560 2561 emit_indirect_jump (offset); 2562 2563 emit_label (after_stub); 2564 return gen_rtx_LABEL_REF (Pmode, stub_start); 2565} 2566 2567/* Set up the registers for passing the handler address and stack offset 2568 to the stub above. */ 2569 2570void 2571expand_builtin_set_eh_regs (handler, offset) 2572 tree handler, offset; 2573{ 2574 rtx reg1, reg2; 2575 2576 eh_regs (®1, ®2, 1); 2577 2578 store_expr (offset, reg2, 0); 2579 store_expr (handler, reg1, 0); 2580 2581 /* These will be used by the stub. */ 2582 emit_insn (gen_rtx_USE (VOIDmode, reg1)); 2583 emit_insn (gen_rtx_USE (VOIDmode, reg2)); 2584} 2585 2586 2587 2588/* This contains the code required to verify whether arbitrary instructions 2589 are in the same exception region. */ 2590 2591static int *insn_eh_region = (int *)0; 2592static int maximum_uid; 2593 2594static void 2595set_insn_eh_region (first, region_num) 2596 rtx *first; 2597 int region_num; 2598{ 2599 rtx insn; 2600 int rnum; 2601 2602 for (insn = *first; insn; insn = NEXT_INSN (insn)) 2603 { 2604 if ((GET_CODE (insn) == NOTE) && 2605 (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)) 2606 { 2607 rnum = NOTE_BLOCK_NUMBER (insn); 2608 insn_eh_region[INSN_UID (insn)] = rnum; 2609 insn = NEXT_INSN (insn); 2610 set_insn_eh_region (&insn, rnum); 2611 /* Upon return, insn points to the EH_REGION_END of nested region */ 2612 continue; 2613 } 2614 insn_eh_region[INSN_UID (insn)] = region_num; 2615 if ((GET_CODE (insn) == NOTE) && 2616 (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)) 2617 break; 2618 } 2619 *first = insn; 2620} 2621 2622/* Free the insn table, an make sure it cannot be used again. */ 2623 2624void 2625free_insn_eh_region () 2626{ 2627 if (!doing_eh (0)) 2628 return; 2629 2630 if (insn_eh_region) 2631 { 2632 free (insn_eh_region); 2633 insn_eh_region = (int *)0; 2634 } 2635} 2636 2637/* Initialize the table. max_uid must be calculated and handed into 2638 this routine. If it is unavailable, passing a value of 0 will 2639 cause this routine to calculate it as well. */ 2640 2641void 2642init_insn_eh_region (first, max_uid) 2643 rtx first; 2644 int max_uid; 2645{ 2646 rtx insn; 2647 2648 if (!doing_eh (0)) 2649 return; 2650 2651 if (insn_eh_region) 2652 free_insn_eh_region(); 2653 2654 if (max_uid == 0) 2655 for (insn = first; insn; insn = NEXT_INSN (insn)) 2656 if (INSN_UID (insn) > max_uid) /* find largest UID */ 2657 max_uid = INSN_UID (insn); 2658 2659 maximum_uid = max_uid; 2660 insn_eh_region = (int *) malloc ((max_uid + 1) * sizeof (int)); 2661 insn = first; 2662 set_insn_eh_region (&insn, 0); 2663} 2664 2665 2666/* Check whether 2 instructions are within the same region. */ 2667 2668int 2669in_same_eh_region (insn1, insn2) 2670 rtx insn1, insn2; 2671{ 2672 int ret, uid1, uid2; 2673 2674 /* If no exceptions, instructions are always in same region. */ 2675 if (!doing_eh (0)) 2676 return 1; 2677 2678 /* If the table isn't allocated, assume the worst. */ 2679 if (!insn_eh_region) 2680 return 0; 2681 2682 uid1 = INSN_UID (insn1); 2683 uid2 = INSN_UID (insn2); 2684 2685 /* if instructions have been allocated beyond the end, either 2686 the table is out of date, or this is a late addition, or 2687 something... Assume the worst. */ 2688 if (uid1 > maximum_uid || uid2 > maximum_uid) 2689 return 0; 2690 2691 ret = (insn_eh_region[uid1] == insn_eh_region[uid2]); 2692 return ret; 2693} 2694 2695