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