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]
Other format: [Raw text]

Re: Itanium unwind patch


On Fri, Dec 14, 2001 at 01:25:32PM -0800, Boehm, Hans wrote:
> Has anyone had a chance to look at
> http://gcc.gnu.org/ml/gcc-patches/2001-11/msg02039.html ?

I've edited it a bit and committed it.

I saw no reason for the #include linux.h hack.  Examining the
preprocessor output, the header _was_ being included, just as
it ought to have been.


r~


        * config/ia64/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.
        * config/ia64/unwind-ia64.c (uw_init_context_1): Redo sp, psp,
        bsp setup.  Set pri_unat_loc to something reasonable.
        (uw_install_context): Add missing cast.
        (unw_access_gr): Fix off-by-1 indexing error.

Index: linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/linux.h,v
retrieving revision 1.13
diff -c -p -d -r1.13 linux.h
*** linux.h	2001/12/15 11:46:52	1.13
--- linux.h	2001/12/28 22:10:00
***************
*** 60,63 ****
  #undef LINK_EH_SPEC
  #define LINK_EH_SPEC ""
  
! /* End of linux.h */
--- 60,122 ----
  #undef LINK_EH_SPEC
  #define LINK_EH_SPEC ""
  
! /* 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>
! 
! #define IA64_GATE_AREA_START 0xa000000000000100LL
! #define IA64_GATE_AREA_END   0xa000000000010000LL
! 
! #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
!   if ((CONTEXT)->rp >= IA64_GATE_AREA_START				\
!       && (CONTEXT)->rp < IA64_GATE_AREA_END)				\
!     {									\
!       struct sigframe {							\
! 	char scratch[16];						\
! 	unsigned long sig_number;					\
! 	struct siginfo *info;						\
! 	struct sigcontext *sc;						\
!       } *frame_ = (struct sigframe *)(CONTEXT)->psp;			\
!       struct sigcontext *sc_ = frame_->sc;				\
! 									\
!       /* Restore scratch registers in case the unwinder needs to	\
! 	 refer to a value stored in one of them.  */			\
!       {									\
! 	int i_;								\
! 									\
! 	for (i_ = 2; i_ < 4; i_++)					\
! 	  (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_];		\
! 	for (i_ = 8; i_ < 12; i_++)					\
! 	  (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_];		\
! 	for (i_ = 14; i_ < 32; i_++)					\
! 	  (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_];		\
!       }									\
! 	  								\
!       (CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs);				\
!       (CONTEXT)->lc_loc = &(sc_->sc_ar_lc);				\
!       (CONTEXT)->unat_loc = &(sc_->sc_ar_unat);				\
!       (CONTEXT)->pr = sc_->sc_pr;					\
!       (CONTEXT)->psp = sc_->sc_gr[12];					\
! 									\
!       /* Don't touch the branch registers.  The kernel doesn't		\
! 	 pass the preserved branch registers in the sigcontext but	\
! 	 leaves them intact, so there's no need to do anything		\
! 	 with them here.  */						\
! 									\
!       {									\
! 	unsigned long sof = sc_->sc_cfm & 0x7f;				\
! 	(CONTEXT)->bsp = (unsigned long)				\
! 	  ia64_rse_skip_regs ((unsigned long *)(sc_->sc_ar_bsp), -sof); \
!       }									\
! 									\
!       (FS)->curr.reg[UNW_REG_RP].where = UNW_WHERE_SPREL;		\
!       (FS)->curr.reg[UNW_REG_RP].val 					\
! 	= (unsigned long)&(sc_->sc_ip) - (CONTEXT)->psp;		\
!       (FS)->curr.reg[UNW_REG_RP].when = -1;				\
! 									\
!       goto SUCCESS;							\
!     }
! #endif /* IN_LIBGCC2 */
Index: unwind-ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/unwind-ia64.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 unwind-ia64.c
*** unwind-ia64.c	2001/08/19 04:55:15	1.2
--- unwind-ia64.c	2001/12/28 22:10:00
***************
*** 36,44 ****
  #include "unwind-ia64.h"
  
  #if !USING_SJLJ_EXCEPTIONS
- 
- #define inline
- 
  #define UNW_VER(x)		((x) >> 48)
  #define UNW_FLAG_MASK		0x0000ffff00000000
  #define UNW_FLAG_OSMASK		0x0000f00000000000
--- 36,41 ----
*************** struct _Unwind_Context
*** 174,180 ****
    unsigned long regstk_top;	/* bsp for first frame */
  
    /* Current frame info.  */
!   unsigned long bsp;		/* backing store pointer value */
    unsigned long sp;		/* stack pointer value */
    unsigned long psp;		/* previous sp value */
    unsigned long rp;		/* return pointer */
--- 171,178 ----
    unsigned long regstk_top;	/* bsp for first frame */
  
    /* Current frame info.  */
!   unsigned long bsp;		/* backing store pointer value
! 				   corresponding to psp.  */
    unsigned long sp;		/* stack pointer value */
    unsigned long psp;		/* previous sp value */
    unsigned long rp;		/* return pointer */
*************** struct _Unwind_Context
*** 203,212 ****
        enum unw_nat_type type : 3;
        signed long off : 61;		/* NaT word is at loc+nat.off */
      } nat;
!   } ireg[32 - 2];
  
    unsigned long *br_loc[7];
    void *fr_loc[32 - 2];
  };
  
  typedef unsigned long unw_word;
--- 201,214 ----
        enum unw_nat_type type : 3;
        signed long off : 61;		/* NaT word is at loc+nat.off */
      } nat;
!   } ireg[32 - 2];	/* Indexed by <register number> - 2 */
  
    unsigned long *br_loc[7];
    void *fr_loc[32 - 2];
+ 
+   /* ??? We initially point pri_unat_loc here.  The entire NAT bit
+      logic needs work.  */
+   unsigned long initial_unat;
  };
  
  typedef unsigned long unw_word;
*************** unw_access_gr (struct _Unwind_Context *i
*** 1317,1323 ****
    else if (regnum < 32)
      {
        /* Access a non-stacked register.  */
!       ireg = &info->ireg[regnum - 1];
        addr = ireg->loc;
        if (addr)
  	{
--- 1319,1325 ----
    else if (regnum < 32)
      {
        /* Access a non-stacked register.  */
!       ireg = &info->ireg[regnum - 2];
        addr = ireg->loc;
        if (addr)
  	{
*************** uw_frame_state_for (struct _Unwind_Conte
*** 1468,1474 ****
      {
        /* Couldn't find unwind info for this function.  Try an
  	 os-specific fallback mechanism.  This will necessarily
! 	 not profide a personality routine or LSDA.  */
  #ifdef MD_FALLBACK_FRAME_STATE_FOR
        MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
  
--- 1470,1476 ----
      {
        /* Couldn't find unwind info for this function.  Try an
  	 os-specific fallback mechanism.  This will necessarily
! 	 not provide a personality routine or LSDA.  */
  #ifdef MD_FALLBACK_FRAME_STATE_FOR
        MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
  
*************** uw_update_context (struct _Unwind_Contex
*** 1727,1764 ****
  }
  
  /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
!    level will be the return address and the CFA.  */
     
! #define uw_init_context(CONTEXT) \
!   uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), __builtin_ia64_bsp ())
  
  static void
! uw_init_context_1 (struct _Unwind_Context *context, void *psp, void *bsp)
  {
    void *rp = __builtin_extract_return_addr (__builtin_return_address (0));
!   void *sp = __builtin_dwarf_cfa ();
    _Unwind_FrameState fs;
  
    /* Flush the register stack to memory so that we can access it.  */
    __builtin_ia64_flushrs ();
  
    memset (context, 0, sizeof (struct _Unwind_Context));
!   context->bsp = (unsigned long) bsp;
!   context->sp = (unsigned long) sp;
    context->psp = (unsigned long) psp;
    context->rp = (unsigned long) rp;
! 
    asm ("mov %0 = pr" : "=r" (context->pr));
    /* ??? Get rnat.  Don't we have to turn off the rse for that?  */
  
    if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
      abort ();
  
-   /* Force the frame state to use the known cfa value.  */
-   fs.curr.reg[UNW_REG_PSP].when = -1;
-   fs.curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE;
-   fs.curr.reg[UNW_REG_PSP].val = sp - psp;
- 
    uw_update_context (context, &fs);
  }
  
--- 1729,1768 ----
  }
  
  /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
!    level will be the return address and the CFA.  Note that CFA = SP+16.  */
     
! #define uw_init_context(CONTEXT)					\
!   do {									\
!     /* ??? There is a whole lot o code in uw_install_context that	\
!        tries to avoid spilling the entire machine state here.  We	\
!        should try to make that work again.  */				\
!     __builtin_unwind_init();						\
!     uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ());			\
!   } while (0)
  
  static void
! uw_init_context_1 (struct _Unwind_Context *context, void *bsp)
  {
    void *rp = __builtin_extract_return_addr (__builtin_return_address (0));
!   /* Set psp to the caller's stack pointer. */
!   void *psp = __builtin_dwarf_cfa () - 16;
    _Unwind_FrameState fs;
  
    /* Flush the register stack to memory so that we can access it.  */
    __builtin_ia64_flushrs ();
  
    memset (context, 0, sizeof (struct _Unwind_Context));
!   context->bsp = context->regstk_top = (unsigned long) bsp;
    context->psp = (unsigned long) psp;
    context->rp = (unsigned long) rp;
!   asm ("mov %0 = sp" : "=r" (context->sp));
    asm ("mov %0 = pr" : "=r" (context->pr));
+   context->pri_unat_loc = &context->initial_unat;	/* ??? */
    /* ??? Get rnat.  Don't we have to turn off the rse for that?  */
  
    if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
      abort ();
  
    uw_update_context (context, &fs);
  }
  
*************** uw_install_context (struct _Unwind_Conte
*** 1791,1798 ****
       target function.  The value that we install below will be
       adjusted by the BR.RET instruction based on the contents
       of AR.PFS.  So we must unadjust that here.  */
!   target->bsp
!     = ia64_rse_skip_regs (target->bsp, (*target->pfs_loc >> 7) & 0x7f);
  
    /* Provide assembly with the offsets into the _Unwind_Context.  */
    asm volatile ("uc_rnat = %0"
--- 1795,1803 ----
       target function.  The value that we install below will be
       adjusted by the BR.RET instruction based on the contents
       of AR.PFS.  So we must unadjust that here.  */
!   target->bsp = (unsigned long)
!     ia64_rse_skip_regs ((unsigned long *)target->bsp,
! 			(*target->pfs_loc >> 7) & 0x7f);
  
    /* Provide assembly with the offsets into the _Unwind_Context.  */
    asm volatile ("uc_rnat = %0"


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