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: [RFC]: MD_FALLBACK_FRAME_STATE_FOR macro for darwin PPC


Geoffrey Keating wrote:


On 20/01/2004, at 12:37 PM, Andreas Tobler wrote:


So, the question is, how do I check inside darwin.h which OS version I have?


You check with code like this:

+    if (*(unsigned int *) (pc_ + 0) != 0x2e1e0032)            \
+      break;                                \
+    if (*(unsigned int *) (pc_ + 4) == 0x40be0050            \
+    || *(unsigned int *) (pc_ + 4) == 0x41920010)            \


You should make enough tests to make sure that you don't falsely identify any darwin version (past or future), by checking every instruction that would have been executed on a return from a signal handler.

Like the diff attached? Or do we need a bigger sequence to make sure that we're on the right track? Also, is the mechanics ok?


Thanks,
Andreas
Index: config/rs6000/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/darwin.h,v
retrieving revision 1.46
diff -u -r1.46 darwin.h
--- config/rs6000/darwin.h	17 Jan 2004 19:48:50 -0000	1.46
+++ config/rs6000/darwin.h	21 Jan 2004 08:42:16 -0000
@@ -1,5 +1,5 @@
 /* Target definitions for PowerPC running Darwin (Mac OS X).
-   Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1997, 2000, 2001, 2003 2004 Free Software Foundation, Inc.
    Contributed by Apple Computer Inc.
 
    This file is part of GCC.
@@ -321,3 +321,78 @@
 #undef REGISTER_TARGET_PRAGMAS
 #define REGISTER_TARGET_PRAGMAS DARWIN_REGISTER_TARGET_PRAGMAS
 
+#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 mcontext *mc_;						\
+    long new_cfa_;							\
+    int i_;								\
+    static unsigned int DARWIN_LIBC_SEQ[] = {				\
+      /* This is the sequence you should enter when catching a signal	\
+	 on Darwin. You find this sequence in libSystem around		\
+	 0x90025158. This is on powerpc-apple-darwin-7.2.0.		\
+	 Other versions	of libSystem may vary.				\
+	 We use this sequence to check if we are on the right		\
+	 OS-X version.  */						\
+									\
+      0x2e1e0032,  /*  cmpwi   cr4,r30,50    */				\
+      0x41920010,  /*  beq-    cr4,9002516c  */				\
+      0x2f9e0037,  /*  cmpwi   cr7,r30,55    */				\
+      0x7fc5f378,  /*  mr      r5,r30        */				\
+      0x40be0050,  /*  bne+    cr7,900251b8  */				\
+      0x807d001c,  /*  lwz     r3,28(r29)    */				\
+      0x3bc30408,  /*  addi    r30,r3,1032   */				\
+      0x7fc4f378,  /*  mr      r4,r30        */				\
+      0x4807b6c9   /*  bl      900a0840      */				\
+    };									\
+									\
+    if (*(unsigned int *) (pc_ + 0) != 0x2e1e0032)			\
+      break;								\
+    if (memcmp(DARWIN_LIBC_SEQ, pc_, sizeof(DARWIN_LIBC_SEQ)) == 0)	\
+      {									\
+	struct sigframe {						\
+	  char redzone[216];						\
+	  struct ucontext uc;						\
+	  siginfo_t st;							\
+	  struct mcontext mc;						\
+	} *rt_ = (CONTEXT)->cfa;					\
+	mc_ = &rt_->mc;							\
+      }									\
+    else								\
+      break;								\
+									\
+    new_cfa_ = mc_->ss.r1;						\
+    (FS)->cfa_how = CFA_REG_OFFSET;					\
+    (FS)->cfa_reg = STACK_POINTER_REGNUM;				\
+    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
+									\
+    /* r0 to r31 are variable names in the ppc_thread_state struct	\
+       since we need the address we just increment the r0 by i_ * 4	\
+       to get the other vars addresses.  */				\
+									\
+    for (i_ = 0; i_ < 32; i_++) {					\
+      if (i_ != STACK_POINTER_REGNUM)					\
+	{								\
+	  (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
+	  (FS)->regs.reg[i_].loc.offset					\
+	    = (long)&(mc_->ss.r0) + (i_*4) - new_cfa_;			\
+	}								\
+    }									\
+									\
+    (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;	\
+    (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset			\
+      = (long)&(mc_->ss.lr) - new_cfa_;					\
+									\
+    (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET;			\
+    (FS)->regs.reg[CR0_REGNO].loc.offset				\
+      = (long)&(mc_->ss.srr0) - new_cfa_;				\
+    (FS)->retaddr_column = CR0_REGNO;					\
+    goto SUCCESS;							\
+  } while (0)

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