[PATCH] MD_FALLBACK_FRAME_STATE_FOR macro for s390

Ulrich Weigand Ulrich.Weigand@de.ibm.com
Wed May 29 07:34:00 GMT 2002


Hello,

this patch adds the MD_FALLBACK_FRAME_STATE_FOR macro for s390/s390x.
This is necessary to allow stack unwinding through signal handler
frames (needed by libjava).

Bootstrapped/regtested on s390-ibm-linux (with libjava active);
fixes a couple of libjava testsuite failures.


ChangeLog:

      * config/s390/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.

Index: gcc/config/s390/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/linux.h,v
retrieving revision 1.20
diff -c -p -r1.20 linux.h
*** gcc/config/s390/linux.h   18 May 2002 23:47:20 -0000    1.20
--- gcc/config/s390/linux.h   29 May 2002 13:39:25 -0000
*************** do {
*** 288,291 ****
--- 288,369 ----
      }                                                                         \
  } while (0)

+ /* Do code reading to identify a signal frame, and set the frame
+    state data appropriately.  See unwind-dw2.c for the structs.  */
+
+ #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)       \
+   do {                                                    \
+     unsigned char *pc_ = (CONTEXT)->ra;                         \
+     long new_cfa_;                                        \
+     int i_;                                               \
+                                                     \
+     typedef struct                                        \
+       {                                                   \
+         unsigned long psw_mask;                                 \
+         unsigned long psw_addr;                                 \
+         unsigned long gprs[16];                                 \
+         unsigned int  acrs[16];                                 \
+         unsigned int  fpc;                                \
+         unsigned int  __pad;                                    \
+         double        fprs[16];                                 \
+       } __attribute__ ((__aligned__ (8))) sigregs_;             \
+                                                     \
+     sigregs_ *regs_;                                      \
+                                                     \
+     /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn  */        \
+     if (pc_[0] != 0x0a || (pc_[1] != 119 && pc_[1] != 173))           \
+       break;                                              \
+                                                     \
+     /* New-style RT frame:                                      \
+     retcode + alignment (8 bytes)                         \
+     siginfo (128 bytes)                                   \
+     ucontext (contains sigregs)  */                             \
+     if ((CONTEXT)->ra == (CONTEXT)->cfa)                        \
+       {                                                   \
+     struct ucontext_                                \
+       {                                             \
+         unsigned long     uc_flags;                             \
+         struct ucontext_ *uc_link;                              \
+         unsigned long     uc_stack[3];                    \
+         sigregs_          uc_mcontext;                    \
+       } *uc_ = (CONTEXT)->cfa + 8 + 128;                        \
+                                                     \
+     regs_ = &uc_->uc_mcontext;                            \
+       }                                                   \
+                                                     \
+     /* Old-style RT frame and all non-RT frames:                \
+     old signal mask (8 bytes)                             \
+     pointer to sigregs  */                                \
+     else                                            \
+       {                                                   \
+     regs_ = *(sigregs_ **)((CONTEXT)->cfa + 8);                 \
+       }                                                   \
+                                                           \
+     new_cfa_ = regs_->gprs[15] + 16*sizeof(long) + 32;                \
+     (FS)->cfa_how = CFA_REG_OFFSET;                             \
+     (FS)->cfa_reg = 15;                                         \
+     (FS)->cfa_offset =                                          \
+       new_cfa_ - (long) (CONTEXT)->cfa + 16*sizeof(long) + 32;        \
+                                                     \
+     for (i_ = 0; i_ < 16; i_++)                                 \
+       {                                                   \
+     (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;                  \
+     (FS)->regs.reg[i_].loc.offset =                       \
+       (long)&regs_->gprs[i_] - new_cfa_;                        \
+       }                                                   \
+     for (i_ = 0; i_ < 16; i_++)                                 \
+       {                                                   \
+     (FS)->regs.reg[16+i_].how = REG_SAVED_OFFSET;               \
+     (FS)->regs.reg[16+i_].loc.offset =                    \
+       (long)&regs_->fprs[i_] - new_cfa_;                        \
+       }                                                   \
+                                                     \
+     /* Load return addr from PSW into dummy register 32.  */          \
+     (FS)->regs.reg[32].how = REG_SAVED_OFFSET;                        \
+     (FS)->regs.reg[32].loc.offset = (long)&regs_->psw_addr - new_cfa_;      \
+     (FS)->retaddr_column = 32;                                  \
+                                                     \
+     goto SUCCESS;                                         \
+   } while (0)
+
  #endif

Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com



More information about the Gcc-patches mailing list