/* We use GNU ld so undefine this so that attribute((init_priority)) works. */
#undef CTORS_SECTION_ASM_OP
#undef DTORS_SECTION_ASM_OP
+
+/* 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; \
+ int new_cfa_, i_, oldstyle_; \
+ int regs_off_, fpu_save_off_; \
+ int fpu_save_, this_cfa_; \
+ \
+ if (pc_[1] != 0x91d02010) /* ta 0x10 */ \
+ break; \
+ if (pc_[0] == 0x821020d8) /* mov NR_sigreturn, %g1 */ \
+ oldstyle_ = 1; \
+ else if (pc_[0] == 0x82102065) /* mov NR_rt_sigreturn, %g1 */ \
+ oldstyle_ = 0; \
+ else \
+ break; \
+ if (oldstyle_) \
+ { \
+ regs_off_ = 96; \
+ fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4); \
+ } \
+ else \
+ { \
+ regs_off_ = 96 + 128; \
+ fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4) + (2 * 4); \
+ } \
+ this_cfa_ = (int) (CONTEXT)->cfa; \
+ new_cfa_ = *(int *)(((CONTEXT)->cfa) + (regs_off_+(4*4)+(14 * 4))); \
+ fpu_save_ = *(int *)((this_cfa_) + (fpu_save_off_)); \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->cfa_reg = 14; \
+ (FS)->cfa_offset = new_cfa_ - (int) (CONTEXT)->cfa; \
+ for (i_ = 1; i_ < 16; ++i_) \
+ { \
+ if (i_ == 14) \
+ continue; \
+ (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_].loc.offset = \
+ this_cfa_ + (regs_off_+(4 * 4)+(i_ * 4)) - new_cfa_; \
+ } \
+ for (i_ = 0; i_ < 16; ++i_) \
+ { \
+ (FS)->regs.reg[i_ + 16].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_ + 16].loc.offset = \
+ this_cfa_ + (i_ * 4) - new_cfa_; \
+ } \
+ if (fpu_save_) \
+ { \
+ for (i_ = 0; i_ < 32; ++i_) \
+ { \
+ (FS)->regs.reg[i_ + 32].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_ + 32].loc.offset = \
+ (fpu_save_ + (i_ * 4)) - new_cfa_; \
+ } \
+ } \
+ /* Stick return address into %g0, same trick Alpha uses. */ \
+ (FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[0].loc.offset = this_cfa_+(regs_off_+4)-new_cfa_; \
+ (FS)->retaddr_column = 0; \
+ goto SUCCESS; \
+ } while (0)
/* We use GNU ld so undefine this so that attribute((init_priority)) works. */
#undef CTORS_SECTION_ASM_OP
#undef DTORS_SECTION_ASM_OP
+
+/* 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
+
+/* Handle multilib correctly. */
+#if defined(__arch64__)
+/* 64-bit Sparc version */
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
+ do { \
+ unsigned int *pc_ = (CONTEXT)->ra; \
+ long new_cfa_, i_; \
+ long regs_off_, fpu_save_off_; \
+ long this_cfa_, fpu_save_; \
+ \
+ if (pc_[0] != 0x82102065 /* mov NR_rt_sigreturn, %g1 */ \
+ || pc_[1] != 0x91d0206d) /* ta 0x6d */ \
+ break; \
+ regs_off_ = 192 + 128; \
+ fpu_save_off_ = regs_off_ + (16 * 8) + (3 * 8) + (2 * 4); \
+ this_cfa_ = (long) (CONTEXT)->cfa; \
+ new_cfa_ = *(long *)(((CONTEXT)->cfa) + (regs_off_ + (14 * 8))); \
+ fpu_save_ = *(long *)((this_cfa_) + (fpu_save_off_)); \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->cfa_reg = 14; \
+ (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
+ for (i_ = 1; i_ < 16; ++i_) \
+ { \
+ if (i_ == 14) \
+ continue; \
+ (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_].loc.offset = \
+ this_cfa_ + (regs_off_ + (i_ * 8)) - new_cfa_; \
+ } \
+ for (i_ = 0; i_ < 16; ++i_) \
+ { \
+ (FS)->regs.reg[i_ + 16].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_ + 16].loc.offset = \
+ this_cfa_ + (i_ * 8) - new_cfa_; \
+ } \
+ if (fpu_save_) \
+ { \
+ for (i_ = 0; i_ < 64; ++i_) \
+ { \
+ if (i_ > 32 && (i_ & 0x1)) \
+ continue; \
+ (FS)->regs.reg[i_ + 32].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_ + 32].loc.offset = \
+ (fpu_save_ + (i_ * 4)) - new_cfa_; \
+ } \
+ } \
+ /* Stick return address into %g0, same trick Alpha uses. */ \
+ (FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[0].loc.offset = \
+ this_cfa_ + (regs_off_ + (16 * 8) + 8) - new_cfa_; \
+ (FS)->retaddr_column = 0; \
+ goto SUCCESS; \
+ } while (0)
+#else
+/* 32-bit Sparc version */
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
+ do { \
+ unsigned int *pc_ = (CONTEXT)->ra; \
+ int new_cfa_, i_, oldstyle_; \
+ int regs_off_, fpu_save_off_; \
+ int fpu_save_, this_cfa_; \
+ \
+ if (pc_[1] != 0x91d02010) /* ta 0x10 */ \
+ break; \
+ if (pc_[0] == 0x821020d8) /* mov NR_sigreturn, %g1 */ \
+ oldstyle_ = 1; \
+ else if (pc_[0] == 0x82102065) /* mov NR_rt_sigreturn, %g1 */ \
+ oldstyle_ = 0; \
+ else \
+ break; \
+ if (oldstyle_) \
+ { \
+ regs_off_ = 96; \
+ fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4); \
+ } \
+ else \
+ { \
+ regs_off_ = 96 + 128; \
+ fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4) + (2 * 4); \
+ } \
+ this_cfa_ = (int) (CONTEXT)->cfa; \
+ new_cfa_ = *(int *)(((CONTEXT)->cfa) + (regs_off_+(4*4)+(14 * 4))); \
+ fpu_save_ = *(int *)((this_cfa_) + (fpu_save_off_)); \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->cfa_reg = 14; \
+ (FS)->cfa_offset = new_cfa_ - (int) (CONTEXT)->cfa; \
+ for (i_ = 1; i_ < 16; ++i_) \
+ { \
+ if (i_ == 14) \
+ continue; \
+ (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_].loc.offset = \
+ this_cfa_ + (regs_off_+(4 * 4)+(i_ * 4)) - new_cfa_; \
+ } \
+ for (i_ = 0; i_ < 16; ++i_) \
+ { \
+ (FS)->regs.reg[i_ + 16].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_ + 16].loc.offset = \
+ this_cfa_ + (i_ * 4) - new_cfa_; \
+ } \
+ if (fpu_save_) \
+ { \
+ for (i_ = 0; i_ < 32; ++i_) \
+ { \
+ (FS)->regs.reg[i_ + 32].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_ + 32].loc.offset = \
+ (fpu_save_ + (i_ * 4)) - new_cfa_; \
+ } \
+ } \
+ /* Stick return address into %g0, same trick Alpha uses. */ \
+ (FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[0].loc.offset = this_cfa_+(regs_off_+4)-new_cfa_; \
+ (FS)->retaddr_column = 0; \
+ goto SUCCESS; \
+ } while (0)
+#endif