This is the mail archive of the gcc@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]

Re: sjlj exceptions


On Wed, Mar 14, 2001 at 05:28:38PM -0800, Mark Mitchell wrote:
> ... as long as the amount of code you have to write to get the desired
> behavior is relatively minimal.

Do you consider this minimal?


r~


$ g++ -g ~/sigtest.cc -fnon-call-exceptions
$ ./a.out
caught 11
caught 11
caught 11
Index: gcc/config/alpha/linux.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/alpha/linux.h,v
retrieving revision 1.21
diff -c -p -d -r1.21 linux.h
*** linux.h	2000/11/09 23:57:41	1.21
--- linux.h	2001/03/15 03:35:00
*************** SUB_CPP_PREDEFINES
*** 44,46 ****
--- 44,97 ----
  
  /* Define this so that all GNU/Linux targets handle the same pragmas.  */
  #define HANDLE_PRAGMA_PACK_PUSH_POP
+ 
+ /* Do code reading to identify a signal frame, and set the frame
+    state data appropriately.  See unwind-dw2.c for the structs.  */
+ 
+ #ifdef IN_LIBGCC2
+ #include <signal.h>
+ #include <sys/ucontext.h>
+ #endif
+ 
+ #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
+   do {									\
+     unsigned int *pc_ = (CONTEXT)->ra;					\
+     struct sigcontext *sc_;						\
+     long new_cfa_, i_;							\
+ 									\
+     if (pc_[0] != 0x47fe0410		/* mov $30,$16 */		\
+         || pc_[2] != 0x00000083		/* callsys */)			\
+       break;								\
+     if (pc_[1] == 0x201f0067)		/* lda $0,NR_sigreturn */	\
+       sc_ = (CONTEXT)->cfa;						\
+     else if (pc_[1] == 0x201f015f)	/* lda $0,NR_rt_sigreturn */	\
+       {									\
+ 	struct rt_sigframe {						\
+ 	  struct siginfo info;						\
+ 	  struct ucontext uc;						\
+ 	} *rt_ = (CONTEXT)->cfa;					\
+ 	sc_ = &rt_->uc.uc_mcontext;					\
+       }									\
+     else								\
+       break;								\
+     new_cfa_ = sc_->sc_regs[30];					\
+     (FS)->cfa_how = CFA_REG_OFFSET;					\
+     (FS)->cfa_reg = 30;							\
+     (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
+     for (i_ = 0; i_ < 30; ++i_)						\
+       {									\
+ 	(FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
+ 	(FS)->regs.reg[i_].loc.offset					\
+ 	  = (long)&sc_->sc_regs[i_] - new_cfa_;				\
+       }									\
+     for (i_ = 0; i_ < 31; ++i_)						\
+       {									\
+ 	(FS)->regs.reg[i_+32].how = REG_SAVED_OFFSET;			\
+ 	(FS)->regs.reg[i_+32].loc.offset				\
+ 	  = (long)&sc_->sc_fpregs[i_] - new_cfa_;			\
+       }									\
+     (FS)->regs.reg[31].how = REG_SAVED_OFFSET;				\
+     (FS)->regs.reg[31].loc.offset = (long)&sc_->sc_pc - new_cfa_;	\
+     (FS)->retaddr_column = 31;						\
+     goto SUCCESS;							\
+   } while (0)
#include <signal.h>
#include <string.h>
#include <stdio.h>

static void handler(int sig)
{
  throw sig;
}

static void killer ()
{
  *(volatile int *) 0;
}

int main()
{
  struct sigaction act;
  int i;

  memset (&act, 0, sizeof act);
  act.sa_handler = handler;
  act.sa_flags = SA_NOMASK;

  sigaction (SIGSEGV, &act, 0);

  for (i = 0; i < 3; ++i)
    {
      try {
	killer ();
      } catch (int sig) {
	printf ("caught %d\n", sig);
      }
    }

  return 0;
}

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