00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "tconfig.h"
00024 #include "tsystem.h"
00025 #include "unwind.h"
00026 #include "unwind-pe.h"
00027
00028 typedef struct
00029 {
00030 _Unwind_Ptr Start;
00031 _Unwind_Ptr LPStart;
00032 _Unwind_Ptr ttype_base;
00033 const unsigned char *TType;
00034 const unsigned char *action_table;
00035 unsigned char ttype_encoding;
00036 unsigned char call_site_encoding;
00037 } lsda_header_info;
00038
00039 static const unsigned char *
00040 parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p,
00041 lsda_header_info *info)
00042 {
00043 _Unwind_Word tmp;
00044 unsigned char lpstart_encoding;
00045
00046 info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
00047
00048
00049 lpstart_encoding = *p++;
00050 if (lpstart_encoding != DW_EH_PE_omit)
00051 p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
00052 else
00053 info->LPStart = info->Start;
00054
00055
00056 info->ttype_encoding = *p++;
00057 if (info->ttype_encoding != DW_EH_PE_omit)
00058 {
00059 p = read_uleb128 (p, &tmp);
00060 info->TType = p + tmp;
00061 }
00062 else
00063 info->TType = 0;
00064
00065
00066
00067 info->call_site_encoding = *p++;
00068 p = read_uleb128 (p, &tmp);
00069 info->action_table = p + tmp;
00070
00071 return p;
00072 }
00073
00074 #ifdef __USING_SJLJ_EXCEPTIONS__
00075 #define PERSONALITY_FUNCTION __gcc_personality_sj0
00076 #define __builtin_eh_return_data_regno(x) x
00077 #else
00078 #define PERSONALITY_FUNCTION __gcc_personality_v0
00079 #endif
00080
00081 _Unwind_Reason_Code
00082 PERSONALITY_FUNCTION (int, _Unwind_Action, _Unwind_Exception_Class,
00083 struct _Unwind_Exception *, struct _Unwind_Context *);
00084
00085 _Unwind_Reason_Code
00086 PERSONALITY_FUNCTION (int version,
00087 _Unwind_Action actions,
00088 _Unwind_Exception_Class exception_class ATTRIBUTE_UNUSED,
00089 struct _Unwind_Exception *ue_header,
00090 struct _Unwind_Context *context)
00091 {
00092 lsda_header_info info;
00093 const unsigned char *language_specific_data, *p, *action_record;
00094 _Unwind_Ptr landing_pad, ip;
00095
00096 if (version != 1)
00097 return _URC_FATAL_PHASE1_ERROR;
00098
00099
00100 if ((actions & _UA_CLEANUP_PHASE) == 0)
00101 return _URC_CONTINUE_UNWIND;
00102
00103 language_specific_data = (const unsigned char *)
00104 _Unwind_GetLanguageSpecificData (context);
00105
00106
00107 if (! language_specific_data)
00108 return _URC_CONTINUE_UNWIND;
00109
00110
00111 p = parse_lsda_header (context, language_specific_data, &info);
00112 ip = _Unwind_GetIP (context) - 1;
00113 landing_pad = 0;
00114
00115 #ifdef __USING_SJLJ_EXCEPTIONS__
00116
00117
00118
00119
00120 if ((int) ip <= 0)
00121 return _URC_CONTINUE_UNWIND;
00122 else
00123 {
00124 _Unwind_Word cs_lp, cs_action;
00125 do
00126 {
00127 p = read_uleb128 (p, &cs_lp);
00128 p = read_uleb128 (p, &cs_action);
00129 }
00130 while (--ip);
00131
00132
00133
00134 landing_pad = cs_lp + 1;
00135 if (cs_action)
00136 action_record = info.action_table + cs_action - 1;
00137 goto found_something;
00138 }
00139 #else
00140
00141 while (p < info.action_table)
00142 {
00143 _Unwind_Ptr cs_start, cs_len, cs_lp;
00144 _Unwind_Word cs_action;
00145
00146
00147 p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
00148 p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
00149 p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
00150 p = read_uleb128 (p, &cs_action);
00151
00152
00153 if (ip < info.Start + cs_start)
00154 p = info.action_table;
00155 else if (ip < info.Start + cs_start + cs_len)
00156 {
00157 if (cs_lp)
00158 landing_pad = info.LPStart + cs_lp;
00159 if (cs_action)
00160 action_record = info.action_table + cs_action - 1;
00161 goto found_something;
00162 }
00163 }
00164
00165 #endif
00166
00167
00168
00169
00170 return _URC_CONTINUE_UNWIND;
00171
00172 found_something:
00173 if (landing_pad == 0)
00174 {
00175
00176
00177 return _URC_CONTINUE_UNWIND;
00178 }
00179
00180 _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
00181 (_Unwind_Ptr) ue_header);
00182 _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), 0);
00183 _Unwind_SetIP (context, landing_pad);
00184 return _URC_INSTALL_CONTEXT;
00185 }