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 #include "unwind.h"
00029
00030
00031
00032 extern void abort (void);
00033
00034 typedef struct _ZSt9type_info type_info;
00035
00036
00037 #define R_IP 12
00038 #define R_SP 13
00039 #define R_LR 14
00040 #define R_PC 15
00041
00042 #define uint32_highbit (((_uw) 1) << 31)
00043
00044 void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp);
00045
00046
00047
00048 typedef struct
00049 {
00050 _uw16 length;
00051 _uw16 offset;
00052 } EHT16;
00053
00054 typedef struct
00055 {
00056 _uw length;
00057 _uw offset;
00058 } EHT32;
00059
00060
00061
00062
00063 static inline _uw
00064 selfrel_offset31 (const _uw *p)
00065 {
00066 _uw offset;
00067
00068 offset = *p;
00069
00070 if (offset & (1 << 30))
00071 offset |= 1u << 31;
00072
00073 return offset + (_uw) p;
00074 }
00075
00076
00077
00078
00079 #define CODE_FINISH (0xb0)
00080
00081
00082
00083 static inline _uw8
00084 next_unwind_byte (__gnu_unwind_state * uws)
00085 {
00086 _uw8 b;
00087
00088 if (uws->bytes_left == 0)
00089 {
00090
00091 if (uws->words_left == 0)
00092 return CODE_FINISH;
00093 uws->words_left--;
00094 uws->data = *(uws->next++);
00095 uws->bytes_left = 3;
00096 }
00097 else
00098 uws->bytes_left--;
00099
00100
00101 b = (uws->data >> 24) & 0xff;
00102 uws->data <<= 8;
00103 return b;
00104 }
00105
00106
00107 _Unwind_Reason_Code
00108 __gnu_unwind_execute (_Unwind_Context * context, __gnu_unwind_state * uws)
00109 {
00110 _uw op;
00111 int set_pc;
00112 _uw reg;
00113
00114 set_pc = 0;
00115 for (;;)
00116 {
00117 op = next_unwind_byte (uws);
00118 if (op == CODE_FINISH)
00119 {
00120
00121 if (!set_pc)
00122 {
00123 _Unwind_VRS_Get (context, _UVRSC_CORE, R_LR, _UVRSD_UINT32,
00124 ®);
00125 _Unwind_VRS_Set (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32,
00126 ®);
00127 set_pc = 1;
00128 }
00129
00130 break;
00131 }
00132 if ((op & 0x80) == 0)
00133 {
00134
00135 _uw offset;
00136
00137 offset = ((op & 0x3f) << 2) + 4;
00138 _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®);
00139 if (op & 0x40)
00140 reg -= offset;
00141 else
00142 reg += offset;
00143 _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®);
00144 continue;
00145 }
00146
00147 if ((op & 0xf0) == 0x80)
00148 {
00149 op = (op << 8) | next_unwind_byte (uws);
00150 if (op == 0x8000)
00151 {
00152
00153 return _URC_FAILURE;
00154 }
00155
00156 op = (op << 4) & 0xfff0;
00157 if (_Unwind_VRS_Pop (context, _UVRSC_CORE, op, _UVRSD_UINT32)
00158 != _UVRSR_OK)
00159 return _URC_FAILURE;
00160 if (op & (1 << R_PC))
00161 set_pc = 1;
00162 continue;
00163 }
00164 if ((op & 0xf0) == 0x90)
00165 {
00166 op &= 0xf;
00167 if (op == 13 || op == 15)
00168
00169 return _URC_FAILURE;
00170
00171 _Unwind_VRS_Get (context, _UVRSC_CORE, op, _UVRSD_UINT32, ®);
00172 _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®);
00173 continue;
00174 }
00175 if ((op & 0xf0) == 0xa0)
00176 {
00177
00178 _uw mask;
00179
00180 mask = (0xff0 >> (7 - (op & 7))) & 0xff0;
00181 if (op & 8)
00182 mask |= (1 << R_LR);
00183 if (_Unwind_VRS_Pop (context, _UVRSC_CORE, mask, _UVRSD_UINT32)
00184 != _UVRSR_OK)
00185 return _URC_FAILURE;
00186 continue;
00187 }
00188 if ((op & 0xf0) == 0xb0)
00189 {
00190
00191 if (op == 0xb1)
00192 {
00193 op = next_unwind_byte (uws);
00194 if (op == 0 || ((op & 0xf0) != 0))
00195
00196 return _URC_FAILURE;
00197
00198 if (_Unwind_VRS_Pop (context, _UVRSC_CORE, op, _UVRSD_UINT32)
00199 != _UVRSR_OK)
00200 return _URC_FAILURE;
00201 continue;
00202 }
00203 if (op == 0xb2)
00204 {
00205
00206 int shift;
00207
00208 _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32,
00209 ®);
00210 op = next_unwind_byte (uws);
00211 shift = 2;
00212 while (op & 0x80)
00213 {
00214 reg += ((op & 0x7f) << shift);
00215 shift += 7;
00216 op = next_unwind_byte (uws);
00217 }
00218 reg += ((op & 0x7f) << shift) + 0x204;
00219 _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32,
00220 ®);
00221 continue;
00222 }
00223 if (op == 0xb3)
00224 {
00225
00226 op = next_unwind_byte (uws);
00227 op = ((op & 0xf0) << 12) | ((op & 0xf) + 1);
00228 if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_VFPX)
00229 != _UVRSR_OK)
00230 return _URC_FAILURE;
00231 continue;
00232 }
00233 if ((op & 0xfc) == 0xb4)
00234 {
00235
00236 op = 0x40000 | ((op & 3) + 1);
00237 if (_Unwind_VRS_Pop (context, _UVRSC_FPA, op, _UVRSD_FPAX)
00238 != _UVRSR_OK)
00239 return _URC_FAILURE;
00240 continue;
00241 }
00242
00243
00244 op = 0x80000 | ((op & 7) + 1);
00245 if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_VFPX)
00246 != _UVRSR_OK)
00247 return _URC_FAILURE;
00248 continue;
00249 }
00250 if ((op & 0xf0) == 0xc0)
00251 {
00252 if (op == 0xc6)
00253 {
00254
00255 op = next_unwind_byte (uws);
00256 op = ((op & 0xf0) << 12) | ((op & 0xf) + 1);
00257 if (_Unwind_VRS_Pop (context, _UVRSC_WMMXD, op, _UVRSD_UINT64)
00258 != _UVRSR_OK)
00259 return _URC_FAILURE;
00260 continue;
00261 }
00262 if (op == 0xc7)
00263 {
00264 op = next_unwind_byte (uws);
00265 if (op == 0 || (op & 0xf0) != 0)
00266
00267 return _URC_FAILURE;
00268
00269 if (_Unwind_VRS_Pop (context, _UVRSC_WMMXC, op, _UVRSD_UINT32)
00270 != _UVRSR_OK)
00271 return _URC_FAILURE;
00272 continue;
00273 }
00274 if ((op & 0xf8) == 0xc0)
00275 {
00276
00277 op = 0xa0000 | ((op & 0xf) + 1);
00278 if (_Unwind_VRS_Pop (context, _UVRSC_WMMXD, op, _UVRSD_UINT64)
00279 != _UVRSR_OK)
00280 return _URC_FAILURE;
00281 continue;
00282 }
00283 if (op == 0xc8)
00284 {
00285
00286 op = next_unwind_byte (uws);
00287 op = ((op & 0xf0) << 12) | ((op & 0xf) + 1);
00288 if (_Unwind_VRS_Pop (context, _UVRSC_FPA, op, _UVRSD_FPAX)
00289 != _UVRSR_OK)
00290 return _URC_FAILURE;
00291 continue;
00292 }
00293 if (op == 0xc9)
00294 {
00295
00296 op = next_unwind_byte (uws);
00297 op = ((op & 0xf0) << 12) | ((op & 0xf) + 1);
00298 if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_DOUBLE)
00299 != _UVRSR_OK)
00300 return _URC_FAILURE;
00301 continue;
00302 }
00303
00304 return _URC_FAILURE;
00305 }
00306 if ((op & 0xf8) == 0xd0)
00307 {
00308
00309 op = 0x80000 | ((op & 7) + 1);
00310 if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_DOUBLE)
00311 != _UVRSR_OK)
00312 return _URC_FAILURE;
00313 continue;
00314 }
00315
00316 return _URC_FAILURE;
00317 }
00318 return _URC_OK;
00319 }
00320
00321
00322
00323
00324
00325
00326 _Unwind_Reason_Code
00327 __gnu_unwind_frame (_Unwind_Control_Block * ucbp, _Unwind_Context * context)
00328 {
00329 _uw *ptr;
00330 __gnu_unwind_state uws;
00331
00332 ptr = (_uw *) ucbp->pr_cache.ehtp;
00333
00334 ptr++;
00335
00336 uws.data = (*ptr) << 8;
00337 uws.next = ptr + 1;
00338 uws.bytes_left = 3;
00339 uws.words_left = ((*ptr) >> 24) & 0xff;
00340
00341 return __gnu_unwind_execute (context, &uws);
00342 }
00343
00344
00345
00346 static inline _Unwind_Control_Block *
00347 unwind_UCB_from_context (_Unwind_Context * context)
00348 {
00349 return (_Unwind_Control_Block *) _Unwind_GetGR (context, R_IP);
00350 }
00351
00352
00353
00354 _Unwind_Ptr
00355 _Unwind_GetRegionStart (_Unwind_Context * context)
00356 {
00357 _Unwind_Control_Block *ucbp;
00358
00359 ucbp = unwind_UCB_from_context (context);
00360 return (_Unwind_Ptr) ucbp->pr_cache.fnstart;
00361 }
00362
00363
00364
00365 void *
00366 _Unwind_GetLanguageSpecificData (_Unwind_Context * context)
00367 {
00368 _Unwind_Control_Block *ucbp;
00369 _uw *ptr;
00370
00371
00372 ucbp = unwind_UCB_from_context (context);
00373 ptr = (_uw *) ucbp->pr_cache.ehtp;
00374
00375 ptr++;
00376
00377 ptr += (((*ptr) >> 24) & 0xff) + 1;
00378
00379 return ptr;
00380 }
00381