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 #if __cplusplus
00027 #define __gxx_abort std::abort
00028 #else
00029 #define __gxx_abort abort
00030 #endif
00031
00032
00033 #define DW_EH_PE_absptr 0x00
00034 #define DW_EH_PE_omit 0xff
00035
00036 #define DW_EH_PE_uleb128 0x01
00037 #define DW_EH_PE_udata2 0x02
00038 #define DW_EH_PE_udata4 0x03
00039 #define DW_EH_PE_udata8 0x04
00040 #define DW_EH_PE_sleb128 0x09
00041 #define DW_EH_PE_sdata2 0x0A
00042 #define DW_EH_PE_sdata4 0x0B
00043 #define DW_EH_PE_sdata8 0x0C
00044 #define DW_EH_PE_signed 0x08
00045
00046 #define DW_EH_PE_pcrel 0x10
00047 #define DW_EH_PE_textrel 0x20
00048 #define DW_EH_PE_datarel 0x30
00049 #define DW_EH_PE_funcrel 0x40
00050 #define DW_EH_PE_aligned 0x50
00051
00052 #define DW_EH_PE_indirect 0x80
00053
00054
00055
00056
00057
00058
00059 static unsigned int
00060 size_of_encoded_value (unsigned char encoding)
00061 {
00062 if (encoding == DW_EH_PE_omit)
00063 return 0;
00064
00065 switch (encoding & 0x07)
00066 {
00067 case DW_EH_PE_absptr:
00068 return sizeof (void *);
00069 case DW_EH_PE_udata2:
00070 return 2;
00071 case DW_EH_PE_udata4:
00072 return 4;
00073 case DW_EH_PE_udata8:
00074 return 8;
00075 }
00076 __gxx_abort ();
00077 }
00078
00079 #ifndef NO_BASE_OF_ENCODED_VALUE
00080
00081
00082
00083
00084
00085
00086 static _Unwind_Ptr
00087 base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
00088 {
00089 if (encoding == DW_EH_PE_omit)
00090 return 0;
00091
00092 switch (encoding & 0x70)
00093 {
00094 case DW_EH_PE_absptr:
00095 case DW_EH_PE_pcrel:
00096 case DW_EH_PE_aligned:
00097 return 0;
00098
00099 case DW_EH_PE_textrel:
00100 return _Unwind_GetTextRelBase (context);
00101 case DW_EH_PE_datarel:
00102 return _Unwind_GetDataRelBase (context);
00103 case DW_EH_PE_funcrel:
00104 return _Unwind_GetRegionStart (context);
00105 }
00106 __gxx_abort ();
00107 }
00108
00109 #endif
00110
00111
00112
00113
00114
00115
00116 static const unsigned char *
00117 read_uleb128 (const unsigned char *p, _Unwind_Word *val)
00118 {
00119 unsigned int shift = 0;
00120 unsigned char byte;
00121 _Unwind_Word result;
00122
00123 result = 0;
00124 do
00125 {
00126 byte = *p++;
00127 result |= (byte & 0x7f) << shift;
00128 shift += 7;
00129 }
00130 while (byte & 0x80);
00131
00132 *val = result;
00133 return p;
00134 }
00135
00136
00137
00138 static const unsigned char *
00139 read_sleb128 (const unsigned char *p, _Unwind_Sword *val)
00140 {
00141 unsigned int shift = 0;
00142 unsigned char byte;
00143 _Unwind_Word result;
00144
00145 result = 0;
00146 do
00147 {
00148 byte = *p++;
00149 result |= (byte & 0x7f) << shift;
00150 shift += 7;
00151 }
00152 while (byte & 0x80);
00153
00154
00155 if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
00156 result |= -(1L << shift);
00157
00158 *val = (_Unwind_Sword) result;
00159 return p;
00160 }
00161
00162
00163
00164
00165
00166 static const unsigned char *
00167 read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
00168 const unsigned char *p, _Unwind_Ptr *val)
00169 {
00170 union unaligned
00171 {
00172 void *ptr;
00173 unsigned u2 __attribute__ ((mode (HI)));
00174 unsigned u4 __attribute__ ((mode (SI)));
00175 unsigned u8 __attribute__ ((mode (DI)));
00176 signed s2 __attribute__ ((mode (HI)));
00177 signed s4 __attribute__ ((mode (SI)));
00178 signed s8 __attribute__ ((mode (DI)));
00179 } __attribute__((__packed__));
00180
00181 union unaligned *u = (union unaligned *) p;
00182 _Unwind_Internal_Ptr result;
00183
00184 if (encoding == DW_EH_PE_aligned)
00185 {
00186 _Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
00187 a = (a + sizeof (void *) - 1) & - sizeof(void *);
00188 result = *(_Unwind_Internal_Ptr *) a;
00189 p = (const unsigned char *) (a + sizeof (void *));
00190 }
00191 else
00192 {
00193 switch (encoding & 0x0f)
00194 {
00195 case DW_EH_PE_absptr:
00196 result = (_Unwind_Internal_Ptr) u->ptr;
00197 p += sizeof (void *);
00198 break;
00199
00200 case DW_EH_PE_uleb128:
00201 {
00202 _Unwind_Word tmp;
00203 p = read_uleb128 (p, &tmp);
00204 result = (_Unwind_Internal_Ptr) tmp;
00205 }
00206 break;
00207
00208 case DW_EH_PE_sleb128:
00209 {
00210 _Unwind_Sword tmp;
00211 p = read_sleb128 (p, &tmp);
00212 result = (_Unwind_Internal_Ptr) tmp;
00213 }
00214 break;
00215
00216 case DW_EH_PE_udata2:
00217 result = u->u2;
00218 p += 2;
00219 break;
00220 case DW_EH_PE_udata4:
00221 result = u->u4;
00222 p += 4;
00223 break;
00224 case DW_EH_PE_udata8:
00225 result = u->u8;
00226 p += 8;
00227 break;
00228
00229 case DW_EH_PE_sdata2:
00230 result = u->s2;
00231 p += 2;
00232 break;
00233 case DW_EH_PE_sdata4:
00234 result = u->s4;
00235 p += 4;
00236 break;
00237 case DW_EH_PE_sdata8:
00238 result = u->s8;
00239 p += 8;
00240 break;
00241
00242 default:
00243 __gxx_abort ();
00244 }
00245
00246 if (result != 0)
00247 {
00248 result += ((encoding & 0x70) == DW_EH_PE_pcrel
00249 ? (_Unwind_Internal_Ptr) u : base);
00250 if (encoding & DW_EH_PE_indirect)
00251 result = *(_Unwind_Internal_Ptr *) result;
00252 }
00253 }
00254
00255 *val = result;
00256 return p;
00257 }
00258
00259 #ifndef NO_BASE_OF_ENCODED_VALUE
00260
00261
00262
00263
00264 static inline const unsigned char *
00265 read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
00266 const unsigned char *p, _Unwind_Ptr *val)
00267 {
00268 return read_encoded_value_with_base (encoding,
00269 base_of_encoded_value (encoding, context),
00270 p, val);
00271 }
00272
00273 #endif