This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch to __throw et al


We were failing to clean up the args space when returning to an exception
handler.  This fixes that and tidies up the code a bit.

Tue Mar 30 13:19:36 1999  Jason Merrill  <jason@yorick.cygnus.com>

	* libgcc2.c (throw_helper): Just return the SP offset, rather than
	a whole udata.  Include args_size in the offset.
	(__throw, __rethrow): Adjust.

Index: libgcc2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/libgcc2.c,v
retrieving revision 1.62
diff -c -p -r1.62 libgcc2.c
*** libgcc2.c	1999/03/24 00:51:16	1.62
--- libgcc2.c	1999/03/30 22:09:46
*************** __unwinding_cleanup ()
*** 3692,3707 ****
     for a dummy call to a routine __unwinding_cleanup() when there are nothing
     but cleanups remaining. This allows a debugger to examine the state
     at which the throw was executed, before any cleanups, rather than
!    at the terminate point after the stack has been unwound. */
  
  static void *
! throw_helper (eh, pc, my_udata, udata_p)
       struct eh_context *eh;
       void *pc;
       frame_state *my_udata;
!      frame_state **udata_p;
  {
!   frame_state *udata = *udata_p;
    frame_state ustruct;
    frame_state *sub_udata = &ustruct;
    void *saved_pc = pc;
--- 3692,3712 ----
     for a dummy call to a routine __unwinding_cleanup() when there are nothing
     but cleanups remaining. This allows a debugger to examine the state
     at which the throw was executed, before any cleanups, rather than
!    at the terminate point after the stack has been unwound.
  
+    EH is the current eh_context structure.
+    PC is the address of the call to __throw.
+    MY_UDATA is the unwind information for __throw.
+    OFFSET_P is where we return the SP adjustment offset.  */
+ 
  static void *
! throw_helper (eh, pc, my_udata, offset_p)
       struct eh_context *eh;
       void *pc;
       frame_state *my_udata;
!      long *offset_p;
  {
!   frame_state ustruct2, *udata = &ustruct2;
    frame_state ustruct;
    frame_state *sub_udata = &ustruct;
    void *saved_pc = pc;
*************** throw_helper (eh, pc, my_udata, udata_p)
*** 3714,3725 ****
--- 3719,3733 ----
    int only_cleanup = 0;
    int rethrow = 0;
    int saved_state = 0;
+   long args_size;
    __eh_info *eh_info = (__eh_info *)eh->info;
  
    /* Do we find a handler based on a re-throw PC? */
    if (eh->table_index != (void *) 0)
      rethrow = 1;
  
+   memcpy (udata, my_udata, sizeof (*udata));
+ 
    handler = (void *) 0;
    for (;;)
      { 
*************** throw_helper (eh, pc, my_udata, udata_p)
*** 3795,3800 ****
--- 3803,3810 ----
  
    eh->handler_label = handler;
  
+   args_size = udata->args_size;
+ 
    if (pc == saved_pc)
      /* We found a handler in the throw context, no need to unwind.  */
      udata = my_udata;
*************** throw_helper (eh, pc, my_udata, udata_p)
*** 3847,3853 ****
      }
    /* udata now refers to the frame called by the handler frame.  */
  
!   *udata_p = udata;
    return handler;
  }
  
--- 3857,3873 ----
      }
    /* udata now refers to the frame called by the handler frame.  */
  
!   /* We adjust SP by the difference between __throw's CFA and the CFA for
!      the frame called by the handler frame, because those CFAs correspond
!      to the SP values at the two call sites.  We need to further adjust by
!      the args_size of the handler frame itself to get the handler frame's
!      SP from before the args were pushed for that call.  */
! #ifdef STACK_GROWS_DOWNWARD
!   *offset_p = udata->cfa - my_udata->cfa + args_size;
! #else
!   *offset_p = my_udata->cfa - udata->cfa - args_size;
! #endif
! 		       
    return handler;
  }
  
*************** __throw ()
*** 3867,3874 ****
  {
    struct eh_context *eh = (*get_eh_context) ();
    void *pc, *handler;
!   frame_state ustruct;
!   frame_state *udata = &ustruct;
    frame_state my_ustruct, *my_udata = &my_ustruct;
  
    /* This is required for C++ semantics.  We must call terminate if we
--- 3887,3896 ----
  {
    struct eh_context *eh = (*get_eh_context) ();
    void *pc, *handler;
!   long offset;
! 
!   /* XXX maybe make my_ustruct static so we don't have to look it up for
!      each throw.  */
    frame_state my_ustruct, *my_udata = &my_ustruct;
  
    /* This is required for C++ semantics.  We must call terminate if we
*************** __throw ()
*** 3879,3892 ****
      
    /* Start at our stack frame.  */
  label:
!   udata = __frame_state_for (&&label, udata);
!   if (! udata)
      __terminate ();
  
    /* We need to get the value from the CFA register. */
!   udata->cfa = __builtin_dwarf_cfa ();
! 
!   memcpy (my_udata, udata, sizeof (*udata));
  
    /* Do any necessary initialization to access arbitrary stack frames.
       On the SPARC, this means flushing the register windows.  */
--- 3901,3912 ----
      
    /* Start at our stack frame.  */
  label:
!   my_udata = __frame_state_for (&&label, my_udata);
!   if (! my_udata)
      __terminate ();
  
    /* We need to get the value from the CFA register. */
!   my_udata->cfa = __builtin_dwarf_cfa ();
  
    /* Do any necessary initialization to access arbitrary stack frames.
       On the SPARC, this means flushing the register windows.  */
*************** label:
*** 3895,3911 ****
    /* Now reset pc to the right throw point.  */
    pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
  
!   handler = throw_helper (eh, pc, my_udata, &udata);
  
    /* Now go!  */
  
!   __builtin_eh_return ((void *)eh,
! #ifdef STACK_GROWS_DOWNWARD
! 		       udata->cfa - my_udata->cfa,
! #else
! 		       my_udata->cfa - udata->cfa,
! #endif
! 		       handler);
  
    /* Epilogue:  restore the handler frame's register values and return
       to the stub.  */
--- 3915,3925 ----
    /* Now reset pc to the right throw point.  */
    pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
  
!   handler = throw_helper (eh, pc, my_udata, &offset);
  
    /* Now go!  */
  
!   __builtin_eh_return ((void *)eh, offset, handler);
  
    /* Epilogue:  restore the handler frame's register values and return
       to the stub.  */
*************** __rethrow (index)
*** 3919,3926 ****
  {
    struct eh_context *eh = (*get_eh_context) ();
    void *pc, *handler;
!   frame_state ustruct;
!   frame_state *udata = &ustruct;
    frame_state my_ustruct, *my_udata = &my_ustruct;
  
    /* This is required for C++ semantics.  We must call terminate if we
--- 3933,3942 ----
  {
    struct eh_context *eh = (*get_eh_context) ();
    void *pc, *handler;
!   long offset;
! 
!   /* XXX maybe make my_ustruct static so we don't have to look it up for
!      each throw.  */
    frame_state my_ustruct, *my_udata = &my_ustruct;
  
    /* This is required for C++ semantics.  We must call terminate if we
*************** __rethrow (index)
*** 3936,3950 ****
      
    /* Start at our stack frame.  */
  label:
!   udata = __frame_state_for (&&label, udata);
!   if (! udata)
      __terminate ();
  
    /* We need to get the value from the CFA register. */
!   udata->cfa = __builtin_dwarf_cfa ();
  
-   memcpy (my_udata, udata, sizeof (*udata));
- 
    /* Do any necessary initialization to access arbitrary stack frames.
       On the SPARC, this means flushing the register windows.  */
    __builtin_unwind_init ();
--- 3952,3964 ----
      
    /* Start at our stack frame.  */
  label:
!   my_udata = __frame_state_for (&&label, my_udata);
!   if (! my_udata)
      __terminate ();
  
    /* We need to get the value from the CFA register. */
!   my_udata->cfa = __builtin_dwarf_cfa ();
  
    /* Do any necessary initialization to access arbitrary stack frames.
       On the SPARC, this means flushing the register windows.  */
    __builtin_unwind_init ();
*************** label:
*** 3952,3968 ****
    /* Now reset pc to the right throw point.  */
    pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
  
!   handler = throw_helper (eh, pc, my_udata, &udata);
  
    /* Now go!  */
  
!   __builtin_eh_return ((void *)eh,
! #ifdef STACK_GROWS_DOWNWARD
! 		       udata->cfa - my_udata->cfa,
! #else
! 		       my_udata->cfa - udata->cfa,
! #endif
! 		       handler);
  
    /* Epilogue:  restore the handler frame's register values and return
       to the stub.  */
--- 3966,3976 ----
    /* Now reset pc to the right throw point.  */
    pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
  
!   handler = throw_helper (eh, pc, my_udata, &offset);
  
    /* Now go!  */
  
!   __builtin_eh_return ((void *)eh, offset, handler);
  
    /* Epilogue:  restore the handler frame's register values and return
       to the stub.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]