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 #include <signal.h>
00033 #include <sys/ucontext.h>
00034 #include <unistd.h>
00035
00036
00037
00038
00039
00040
00041 #define MD_FALLBACK_FRAME_STATE_FOR pa_fallback_frame_state
00042
00043
00044 #ifndef GetSSReg
00045 #define GetSSReg(ssp, ss_reg) \
00046 ((UseWideRegs (ssp)) \
00047 ? (ssp)->ss_wide.ss_32.ss_reg ## _lo \
00048 : (ssp)->ss_narrow.ss_reg)
00049 #endif
00050
00051 #if TARGET_64BIT
00052 #define GetSSRegAddr(ssp, ss_reg) ((long) &((ssp)->ss_wide.ss_64.ss_reg))
00053 #else
00054 #define GetSSRegAddr(ssp, ss_reg) \
00055 ((UseWideRegs (ssp)) \
00056 ? (long) &((ssp)->ss_wide.ss_32.ss_reg ## _lo) \
00057 : (long) &((ssp)->ss_narrow.ss_reg))
00058 #endif
00059
00060 #define UPDATE_FS_FOR_SAR(FS, N) \
00061 (FS)->regs.reg[N].how = REG_SAVED_OFFSET; \
00062 (FS)->regs.reg[N].loc.offset = GetSSRegAddr (mc, ss_cr11) - new_cfa
00063
00064 #define UPDATE_FS_FOR_GR(FS, GRN, N) \
00065 (FS)->regs.reg[N].how = REG_SAVED_OFFSET; \
00066 (FS)->regs.reg[N].loc.offset = GetSSRegAddr (mc, ss_gr##GRN) - new_cfa
00067
00068 #define UPDATE_FS_FOR_FR(FS, FRN, N) \
00069 (FS)->regs.reg[N].how = REG_SAVED_OFFSET; \
00070 (FS)->regs.reg[N].loc.offset = (long) &(mc->ss_fr##FRN) - new_cfa;
00071
00072 #define UPDATE_FS_FOR_PC(FS, N) \
00073 (FS)->regs.reg[N].how = REG_SAVED_OFFSET; \
00074 (FS)->regs.reg[N].loc.offset = GetSSRegAddr (mc, ss_pcoq_head) - new_cfa
00075
00076
00077 #define GET_FIELD(X, FROM, TO) \
00078 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
00079
00080 static inline int
00081 sign_extend (int x, int len)
00082 {
00083 int signbit = (1 << (len - 1));
00084 int mask = (signbit << 1) - 1;
00085 return ((x & mask) ^ signbit) - signbit;
00086 }
00087
00088
00089 static inline int
00090 extract_17 (unsigned word)
00091 {
00092 return sign_extend (GET_FIELD (word, 19, 28)
00093 | GET_FIELD (word, 29, 29) << 10
00094 | GET_FIELD (word, 11, 15) << 11
00095 | (word & 0x1) << 16, 17);
00096 }
00097
00098
00099 static inline int
00100 extract_22 (unsigned word)
00101 {
00102 return sign_extend (GET_FIELD (word, 19, 28)
00103 | GET_FIELD (word, 29, 29) << 10
00104 | GET_FIELD (word, 11, 15) << 11
00105 | GET_FIELD (word, 6, 10) << 16
00106 | (word & 0x1) << 21, 22);
00107 }
00108
00109 static _Unwind_Reason_Code
00110 pa_fallback_frame_state (struct _Unwind_Context *context,
00111 _Unwind_FrameState *fs)
00112 {
00113 static long cpu;
00114 unsigned int *pc = (unsigned int *) context->ra;
00115
00116 if (pc == 0)
00117 return _URC_END_OF_STACK;
00118
00119
00120 if (!TARGET_64BIT
00121 && *(pc + 0) == 0x2fd01224
00122 && *(pc + 1) == 0x0fd9109d
00123 && *(pc + 2) == 0x0fd130bc)
00124 pc += 3;
00125 else if (!TARGET_64BIT
00126 && *(pc + 0) == 0x27d01224
00127 && *(pc + 1) == 0x0fd130bc)
00128 pc += 2;
00129 else if (!TARGET_64BIT
00130 && *(pc + 0) == 0x0fdc12b0
00131 && *(pc + 1) == 0x0fdd1299
00132 && *(pc + 2) == 0x2fd13024)
00133 pc += 3;
00134 else if (!TARGET_64BIT
00135 && *(pc + 0) == 0x0fdc12b0
00136 && *(pc + 1) == 0x27d13024)
00137 pc += 2;
00138
00139
00140 if ((!TARGET_64BIT
00141 && *(pc + 0) == 0x4bc23fd1
00142 && *(pc + 1) == 0x004010a1
00143 && *(pc + 2) == 0x00011820
00144 && *(pc + 3) == 0xe0400002)
00145 ||
00146 (!TARGET_64BIT
00147 && *(pc + 0) == 0x4bc23fd1
00148 && *(pc + 1) == 0xe840d002))
00149 {
00150 fs->cfa_how = CFA_REG_OFFSET;
00151 fs->cfa_reg = 30;
00152 fs->cfa_offset = 0;
00153
00154 fs->retaddr_column = 0;
00155 fs->regs.reg[0].how = REG_SAVED_OFFSET;
00156 fs->regs.reg[0].loc.offset = -24;
00157
00158
00159 uw_update_context (context, fs);
00160
00161
00162 return uw_frame_state_for (context, fs);
00163 }
00164
00165 else if (!TARGET_64BIT
00166 && *(pc + 0) == 0x0fd11082
00167 && (*(pc + 1) == 0xe840c002
00168 || *(pc + 1) == 0xe840d002))
00169 {
00170 fs->cfa_how = CFA_REG_OFFSET;
00171 fs->cfa_reg = 30;
00172 fs->cfa_offset = 0;
00173
00174 fs->retaddr_column = 0;
00175 fs->regs.reg[0].how = REG_SAVED_OFFSET;
00176 fs->regs.reg[0].loc.offset = -8;
00177
00178
00179 uw_update_context (context, fs);
00180
00181
00182 return uw_frame_state_for (context, fs);
00183 }
00184
00185
00186
00187 if (!TARGET_64BIT
00188 && (*pc & 0xffe0e002) == 0xe8400000
00189 && *(pc + 1) == 0x08000240
00190 && *(pc + 2) == 0x4bc23fd1
00191 && *(pc + 3) == 0x004010a1
00192 && *(pc + 4) == 0x00011820
00193 && *(pc + 5) == 0xe0400002)
00194
00195 pc += extract_17 (*pc) + 2;
00196 else if (!TARGET_64BIT
00197 && (*pc & 0xfc00e002) == 0xe800a000
00198 && *(pc + 1) == 0x08000240
00199 && *(pc + 2) == 0x4bc23fd1
00200 && *(pc + 3) == 0xe840d002)
00201
00202 pc += extract_22 (*pc) + 2;
00203
00204
00205
00206 if ((TARGET_64BIT
00207 && *(pc + 0) == 0x53db3f51
00208 && *(pc + 8) == 0x34160116
00209 && *(pc + 9) == 0x08360ac1
00210 && *(pc + 10) == 0x0c2010c1
00211 && *(pc + 11) == 0xe4202000)
00212 ||
00213 (TARGET_64BIT
00214 && *(pc + 0) == 0x36dc0000
00215 && *(pc + 6) == 0x341601c0
00216 && *(pc + 7) == 0x08360ac1
00217 && *(pc + 8) == 0x0c2010c1
00218 && *(pc + 9) == 0xe4202000)
00219 ||
00220 (!TARGET_64BIT
00221 && *(pc + 0) == 0x379a0000
00222 && *(pc + 1) == 0x6bd33fc9
00223 && *(pc + 2) == 0x20200801
00224 && *(pc + 3) == 0xe420e008
00225 && *(pc + 4) == 0x34160116)
00226 ||
00227 (!TARGET_64BIT
00228 && *(pc + 0) == 0x6bd33fc9
00229 && *(pc + 1) == 0x20200801
00230 && *(pc + 2) == 0xe420e008
00231 && *(pc + 3) == 0x341601c0))
00232 {
00233
00234
00235
00236 struct siglocalx *sl = (struct siglocalx *)
00237 (*((long *) context->cfa - 1));
00238 mcontext_t *mc = &(sl->sl_uc.uc_mcontext);
00239
00240 long new_cfa = GetSSReg (mc, ss_sp);
00241
00242 fs->cfa_how = CFA_REG_OFFSET;
00243 fs->cfa_reg = 30;
00244 fs->cfa_offset = new_cfa - (long) context->cfa;
00245
00246 UPDATE_FS_FOR_GR (fs, 1, 1);
00247 UPDATE_FS_FOR_GR (fs, 2, 2);
00248 UPDATE_FS_FOR_GR (fs, 3, 3);
00249 UPDATE_FS_FOR_GR (fs, 4, 4);
00250 UPDATE_FS_FOR_GR (fs, 5, 5);
00251 UPDATE_FS_FOR_GR (fs, 6, 6);
00252 UPDATE_FS_FOR_GR (fs, 7, 7);
00253 UPDATE_FS_FOR_GR (fs, 8, 8);
00254 UPDATE_FS_FOR_GR (fs, 9, 9);
00255 UPDATE_FS_FOR_GR (fs, 10, 10);
00256 UPDATE_FS_FOR_GR (fs, 11, 11);
00257 UPDATE_FS_FOR_GR (fs, 12, 12);
00258 UPDATE_FS_FOR_GR (fs, 13, 13);
00259 UPDATE_FS_FOR_GR (fs, 14, 14);
00260 UPDATE_FS_FOR_GR (fs, 15, 15);
00261 UPDATE_FS_FOR_GR (fs, 16, 16);
00262 UPDATE_FS_FOR_GR (fs, 17, 17);
00263 UPDATE_FS_FOR_GR (fs, 18, 18);
00264 UPDATE_FS_FOR_GR (fs, 19, 19);
00265 UPDATE_FS_FOR_GR (fs, 20, 20);
00266 UPDATE_FS_FOR_GR (fs, 21, 21);
00267 UPDATE_FS_FOR_GR (fs, 22, 22);
00268 UPDATE_FS_FOR_GR (fs, 23, 23);
00269 UPDATE_FS_FOR_GR (fs, 24, 24);
00270 UPDATE_FS_FOR_GR (fs, 25, 25);
00271 UPDATE_FS_FOR_GR (fs, 26, 26);
00272 UPDATE_FS_FOR_GR (fs, 27, 27);
00273 UPDATE_FS_FOR_GR (fs, 28, 28);
00274 UPDATE_FS_FOR_GR (fs, 29, 29);
00275 UPDATE_FS_FOR_GR (fs, 30, 30);
00276 UPDATE_FS_FOR_GR (fs, 31, 31);
00277
00278 if (TARGET_64BIT)
00279 {
00280 UPDATE_FS_FOR_FR (fs, 4, 32);
00281 UPDATE_FS_FOR_FR (fs, 5, 33);
00282 UPDATE_FS_FOR_FR (fs, 6, 34);
00283 UPDATE_FS_FOR_FR (fs, 7, 35);
00284 UPDATE_FS_FOR_FR (fs, 8, 36);
00285 UPDATE_FS_FOR_FR (fs, 9, 37);
00286 UPDATE_FS_FOR_FR (fs, 10, 38);
00287 UPDATE_FS_FOR_FR (fs, 11, 39);
00288 UPDATE_FS_FOR_FR (fs, 12, 40);
00289 UPDATE_FS_FOR_FR (fs, 13, 41);
00290 UPDATE_FS_FOR_FR (fs, 14, 42);
00291 UPDATE_FS_FOR_FR (fs, 15, 43);
00292 UPDATE_FS_FOR_FR (fs, 16, 44);
00293 UPDATE_FS_FOR_FR (fs, 17, 45);
00294 UPDATE_FS_FOR_FR (fs, 18, 46);
00295 UPDATE_FS_FOR_FR (fs, 19, 47);
00296 UPDATE_FS_FOR_FR (fs, 20, 48);
00297 UPDATE_FS_FOR_FR (fs, 21, 49);
00298 UPDATE_FS_FOR_FR (fs, 22, 50);
00299 UPDATE_FS_FOR_FR (fs, 23, 51);
00300 UPDATE_FS_FOR_FR (fs, 24, 52);
00301 UPDATE_FS_FOR_FR (fs, 25, 53);
00302 UPDATE_FS_FOR_FR (fs, 26, 54);
00303 UPDATE_FS_FOR_FR (fs, 27, 55);
00304 UPDATE_FS_FOR_FR (fs, 28, 56);
00305 UPDATE_FS_FOR_FR (fs, 29, 57);
00306 UPDATE_FS_FOR_FR (fs, 30, 58);
00307 UPDATE_FS_FOR_FR (fs, 31, 59);
00308
00309 UPDATE_FS_FOR_SAR (fs, 60);
00310 }
00311 else
00312 {
00313 UPDATE_FS_FOR_FR (fs, 4, 32);
00314 UPDATE_FS_FOR_FR (fs, 5, 34);
00315 UPDATE_FS_FOR_FR (fs, 6, 36);
00316 UPDATE_FS_FOR_FR (fs, 7, 38);
00317 UPDATE_FS_FOR_FR (fs, 8, 40);
00318 UPDATE_FS_FOR_FR (fs, 9, 44);
00319 UPDATE_FS_FOR_FR (fs, 10, 44);
00320 UPDATE_FS_FOR_FR (fs, 11, 46);
00321 UPDATE_FS_FOR_FR (fs, 12, 48);
00322 UPDATE_FS_FOR_FR (fs, 13, 50);
00323 UPDATE_FS_FOR_FR (fs, 14, 52);
00324 UPDATE_FS_FOR_FR (fs, 15, 54);
00325
00326 if (!cpu)
00327 cpu = sysconf (_SC_CPU_VERSION);
00328
00329
00330 if (cpu != CPU_PA_RISC1_0)
00331 {
00332 UPDATE_FS_FOR_FR (fs, 16, 56);
00333 UPDATE_FS_FOR_FR (fs, 17, 58);
00334 UPDATE_FS_FOR_FR (fs, 18, 60);
00335 UPDATE_FS_FOR_FR (fs, 19, 62);
00336 UPDATE_FS_FOR_FR (fs, 20, 64);
00337 UPDATE_FS_FOR_FR (fs, 21, 66);
00338 UPDATE_FS_FOR_FR (fs, 22, 68);
00339 UPDATE_FS_FOR_FR (fs, 23, 70);
00340 UPDATE_FS_FOR_FR (fs, 24, 72);
00341 UPDATE_FS_FOR_FR (fs, 25, 74);
00342 UPDATE_FS_FOR_FR (fs, 26, 76);
00343 UPDATE_FS_FOR_FR (fs, 27, 78);
00344 UPDATE_FS_FOR_FR (fs, 28, 80);
00345 UPDATE_FS_FOR_FR (fs, 29, 82);
00346 UPDATE_FS_FOR_FR (fs, 30, 84);
00347 UPDATE_FS_FOR_FR (fs, 31, 86);
00348 }
00349
00350 UPDATE_FS_FOR_SAR (fs, 88);
00351 }
00352
00353 fs->retaddr_column = DWARF_ALT_FRAME_RETURN_COLUMN;
00354 UPDATE_FS_FOR_PC (fs, DWARF_ALT_FRAME_RETURN_COLUMN);
00355
00356 return _URC_NO_REASON;
00357 }
00358
00359 return _URC_END_OF_STACK;
00360 }