OSDN Git Service

2003-01-23 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
authorsirl <sirl@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Jan 2003 22:28:48 +0000 (22:28 +0000)
committersirl <sirl@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Jan 2003 22:28:48 +0000 (22:28 +0000)
PR java/6748
* config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Don't destroy
regs->nip. Fix rt_sigreturn frame layout. Add support for newer
kernels.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@61675 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/linux.h

index 486a73f..e0af5c5 100644 (file)
@@ -1,3 +1,10 @@
+2003-01-23  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
+
+       PR java/6748
+       * config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Don't destroy
+       regs->nip. Fix rt_sigreturn frame layout. Add support for newer
+       kernels.
+
 2003-01-23  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * cpplex.c (cpp_interpret_charconst): Squelch warning with cast.
index 1711354..bb195d0 100644 (file)
@@ -1,7 +1,7 @@
 /* Definitions of target machine for GNU compiler,
    for PowerPC machines running Linux.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, 
-   Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
    Contributed by Michael Meissner (meissner@cygnus.com).
 
 This file is part of GNU CC.
@@ -96,12 +96,34 @@ enum { SIGNAL_FRAMESIZE = 64 };
     long new_cfa_;                                                     \
     int i_;                                                            \
                                                                        \
-    /* li r0, 0x7777; sc  (rt_sigreturn)  */                           \
-    /* li r0, 0x6666; sc  (sigreturn)  */                              \
-    if (((*(unsigned int *) (pc_+0) == 0x38007777)                     \
-        || (*(unsigned int *) (pc_+0) == 0x38006666))                  \
-       && (*(unsigned int *) (pc_+4)  == 0x44000002))                  \
-       sc_ = (CONTEXT)->cfa + SIGNAL_FRAMESIZE;                        \
+    /* li r0, 0x7777; sc  (sigreturn old)  */                          \
+    /* li r0, 0x0077; sc  (sigreturn new)  */                          \
+    /* li r0, 0x6666; sc  (rt_sigreturn old)  */                       \
+    /* li r0, 0x00AC; sc  (rt_sigreturn new)  */                       \
+    if (*(unsigned int *) (pc_+4) != 0x44000002)                       \
+      break;                                                           \
+    if (*(unsigned int *) (pc_+0) == 0x38007777                                \
+       || *(unsigned int *) (pc_+0) == 0x38000077)                     \
+      {                                                                        \
+       struct sigframe {                                               \
+         char gap[SIGNAL_FRAMESIZE];                                   \
+         struct sigcontext sigctx;                                     \
+       } *rt_ = (CONTEXT)->cfa;                                        \
+       sc_ = &rt_->sigctx;                                             \
+      }                                                                        \
+    else if (*(unsigned int *) (pc_+0) == 0x38006666                   \
+            || *(unsigned int *) (pc_+0) == 0x380000AC)                \
+      {                                                                        \
+       struct rt_sigframe {                                            \
+         char gap[SIGNAL_FRAMESIZE];                                   \
+         unsigned long _unused[2];                                     \
+         struct siginfo *pinfo;                                        \
+         void *puc;                                                    \
+         struct siginfo info;                                          \
+         struct ucontext uc;                                           \
+       } *rt_ = (CONTEXT)->cfa;                                        \
+       sc_ = &rt_->uc.uc_mcontext;                                     \
+      }                                                                        \
     else                                                               \
       break;                                                           \
                                                                        \
@@ -124,11 +146,13 @@ enum { SIGNAL_FRAMESIZE = 64 };
                                                                        \
     /* The unwinder expects the IP to point to the following insn,     \
        whereas the kernel returns the address of the actual            \
-       faulting insn.  */                                              \
-    sc_->regs->nip += 4;                                               \
+       faulting insn. We store NIP+4 in an unused register slot to     \
+       get the same result for multiple evaluation of the same signal  \
+       frame.  */                                                      \
+    sc_->regs->gpr[47] = sc_->regs->nip + 4;                           \
     (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET;                  \
     (FS)->regs.reg[CR0_REGNO].loc.offset                               \
-      = (long)&(sc_->regs->nip) - new_cfa_;                            \
+      = (long)&(sc_->regs->gpr[47]) - new_cfa_;                                \
     (FS)->retaddr_column = CR0_REGNO;                                  \
     goto SUCCESS;                                                      \
   } while (0)