00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #if defined(__arch64__)
00034
00035
00036 #define MD_FALLBACK_FRAME_STATE_FOR sparc64_fallback_frame_state
00037
00038 static _Unwind_Reason_Code
00039 sparc64_fallback_frame_state (struct _Unwind_Context *context,
00040 _Unwind_FrameState *fs)
00041 {
00042 unsigned int *pc = context->ra;
00043 long new_cfa, i;
00044 long regs_off, fpu_save_off;
00045 long this_cfa, fpu_save;
00046
00047 if (pc[0] != 0x82102065
00048 || pc[1] != 0x91d0206d)
00049 return _URC_END_OF_STACK;
00050 regs_off = 192 + 128;
00051 fpu_save_off = regs_off + (16 * 8) + (3 * 8) + (2 * 4);
00052 this_cfa = (long) context->cfa;
00053 new_cfa = *(long *)((context->cfa) + (regs_off + (14 * 8)));
00054 new_cfa += 2047;
00055 fpu_save = *(long *)((this_cfa) + (fpu_save_off));
00056 fs->cfa_how = CFA_REG_OFFSET;
00057 fs->cfa_reg = 14;
00058 fs->cfa_offset = new_cfa - (long) context->cfa;
00059 for (i = 1; i < 16; ++i)
00060 {
00061 fs->regs.reg[i].how = REG_SAVED_OFFSET;
00062 fs->regs.reg[i].loc.offset =
00063 this_cfa + (regs_off + (i * 8)) - new_cfa;
00064 }
00065 for (i = 0; i < 16; ++i)
00066 {
00067 fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
00068 fs->regs.reg[i + 16].loc.offset =
00069 this_cfa + (i * 8) - new_cfa;
00070 }
00071 if (fpu_save)
00072 {
00073 for (i = 0; i < 64; ++i)
00074 {
00075 if (i > 32 && (i & 0x1))
00076 continue;
00077 fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
00078 fs->regs.reg[i + 32].loc.offset =
00079 (fpu_save + (i * 4)) - new_cfa;
00080 }
00081 }
00082
00083 fs->regs.reg[0].how = REG_SAVED_OFFSET;
00084 fs->regs.reg[0].loc.offset =
00085 this_cfa + (regs_off + (16 * 8) + 8) - new_cfa;
00086 fs->retaddr_column = 0;
00087 return _URC_NO_REASON;
00088 }
00089
00090 #else
00091
00092
00093 #define MD_FALLBACK_FRAME_STATE_FOR sparc_fallback_frame_state
00094
00095 static _Unwind_Reason_Code
00096 sparc_fallback_frame_state (struct _Unwind_Context *context,
00097 _Unwind_FrameState *fs)
00098 {
00099 unsigned int *pc = context->ra;
00100 int new_cfa, i, oldstyle;
00101 int regs_off, fpu_save_off;
00102 int fpu_save, this_cfa;
00103
00104 if (pc[1] != 0x91d02010)
00105 return _URC_END_OF_STACK;
00106 if (pc[0] == 0x821020d8)
00107 oldstyle = 1;
00108 else if (pc[0] == 0x82102065)
00109 oldstyle = 0;
00110 else
00111 return _URC_END_OF_STACK;
00112 if (oldstyle)
00113 {
00114 regs_off = 96;
00115 fpu_save_off = regs_off + (4 * 4) + (16 * 4);
00116 }
00117 else
00118 {
00119 regs_off = 96 + 128;
00120 fpu_save_off = regs_off + (4 * 4) + (16 * 4) + (2 * 4);
00121 }
00122 this_cfa = (int) context->cfa;
00123 new_cfa = *(int *)((context->cfa) + (regs_off+(4*4)+(14 * 4)));
00124 fpu_save = *(int *)((this_cfa) + (fpu_save_off));
00125 fs->cfa_how = CFA_REG_OFFSET;
00126 fs->cfa_reg = 14;
00127 fs->cfa_offset = new_cfa - (int) context->cfa;
00128 for (i = 1; i < 16; ++i)
00129 {
00130 if (i == 14)
00131 continue;
00132 fs->regs.reg[i].how = REG_SAVED_OFFSET;
00133 fs->regs.reg[i].loc.offset =
00134 this_cfa + (regs_off+(4 * 4)+(i * 4)) - new_cfa;
00135 }
00136 for (i = 0; i < 16; ++i)
00137 {
00138 fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
00139 fs->regs.reg[i + 16].loc.offset =
00140 this_cfa + (i * 4) - new_cfa;
00141 }
00142 if (fpu_save)
00143 {
00144 for (i = 0; i < 32; ++i)
00145 {
00146 fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
00147 fs->regs.reg[i + 32].loc.offset =
00148 (fpu_save + (i * 4)) - new_cfa;
00149 }
00150 }
00151
00152 fs->regs.reg[0].how = REG_SAVED_OFFSET;
00153 fs->regs.reg[0].loc.offset = this_cfa+(regs_off+4)-new_cfa;
00154 fs->retaddr_column = 0;
00155 return _URC_NO_REASON;
00156 }
00157
00158 #endif