OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [unwind-pe.h] - Blame information for rev 154

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Exception handling and frame unwind runtime interface routines.
2
   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
3
 
4
   This file is part of GCC.
5
 
6
   GCC is free software; you can redistribute it and/or modify it
7
   under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 2, or (at your option)
9
   any later version.
10
 
11
   In addition to the permissions in the GNU General Public License, the
12
   Free Software Foundation gives you unlimited permission to link the
13
   compiled version of this file into combinations with other programs,
14
   and to distribute those combinations without any restriction coming
15
   from the use of this file.  (The General Public License restrictions
16
   do apply in other respects; for example, they cover modification of
17
   the file, and distribution when not linked into a combined
18
   executable.)
19
 
20
   GCC is distributed in the hope that it will be useful, but WITHOUT
21
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
23
   License for more details.
24
 
25
   You should have received a copy of the GNU General Public License
26
   along with GCC; see the file COPYING.  If not, write to the Free
27
   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
28
   02110-1301, USA.  */
29
 
30
/* @@@ Really this should be out of line, but this also causes link
31
   compatibility problems with the base ABI.  This is slightly better
32
   than duplicating code, however.  */
33
 
34
#ifndef GCC_UNWIND_PE_H
35
#define GCC_UNWIND_PE_H
36
 
37
/* If using C++, references to abort have to be qualified with std::.  */
38
#if __cplusplus
39
#define __gxx_abort std::abort
40
#else
41
#define __gxx_abort abort
42
#endif
43
 
44
/* Pointer encodings, from dwarf2.h.  */
45
#define DW_EH_PE_absptr         0x00
46
#define DW_EH_PE_omit           0xff
47
 
48
#define DW_EH_PE_uleb128        0x01
49
#define DW_EH_PE_udata2         0x02
50
#define DW_EH_PE_udata4         0x03
51
#define DW_EH_PE_udata8         0x04
52
#define DW_EH_PE_sleb128        0x09
53
#define DW_EH_PE_sdata2         0x0A
54
#define DW_EH_PE_sdata4         0x0B
55
#define DW_EH_PE_sdata8         0x0C
56
#define DW_EH_PE_signed         0x08
57
 
58
#define DW_EH_PE_pcrel          0x10
59
#define DW_EH_PE_textrel        0x20
60
#define DW_EH_PE_datarel        0x30
61
#define DW_EH_PE_funcrel        0x40
62
#define DW_EH_PE_aligned        0x50
63
 
64
#define DW_EH_PE_indirect       0x80
65
 
66
 
67
#ifndef NO_SIZE_OF_ENCODED_VALUE
68
 
69
/* Given an encoding, return the number of bytes the format occupies.
70
   This is only defined for fixed-size encodings, and so does not
71
   include leb128.  */
72
 
73
static unsigned int
74
size_of_encoded_value (unsigned char encoding)
75
{
76
  if (encoding == DW_EH_PE_omit)
77
    return 0;
78
 
79
  switch (encoding & 0x07)
80
    {
81
    case DW_EH_PE_absptr:
82
      return sizeof (void *);
83
    case DW_EH_PE_udata2:
84
      return 2;
85
    case DW_EH_PE_udata4:
86
      return 4;
87
    case DW_EH_PE_udata8:
88
      return 8;
89
    }
90
  __gxx_abort ();
91
}
92
 
93
#endif
94
 
95
#ifndef NO_BASE_OF_ENCODED_VALUE
96
 
97
/* Given an encoding and an _Unwind_Context, return the base to which
98
   the encoding is relative.  This base may then be passed to
99
   read_encoded_value_with_base for use when the _Unwind_Context is
100
   not available.  */
101
 
102
static _Unwind_Ptr
103
base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
104
{
105
  if (encoding == DW_EH_PE_omit)
106
    return 0;
107
 
108
  switch (encoding & 0x70)
109
    {
110
    case DW_EH_PE_absptr:
111
    case DW_EH_PE_pcrel:
112
    case DW_EH_PE_aligned:
113
      return 0;
114
 
115
    case DW_EH_PE_textrel:
116
      return _Unwind_GetTextRelBase (context);
117
    case DW_EH_PE_datarel:
118
      return _Unwind_GetDataRelBase (context);
119
    case DW_EH_PE_funcrel:
120
      return _Unwind_GetRegionStart (context);
121
    }
122
  __gxx_abort ();
123
}
124
 
125
#endif
126
 
127
/* Read an unsigned leb128 value from P, store the value in VAL, return
128
   P incremented past the value.  We assume that a word is large enough to
129
   hold any value so encoded; if it is smaller than a pointer on some target,
130
   pointers should not be leb128 encoded on that target.  */
131
 
132
static const unsigned char *
133
read_uleb128 (const unsigned char *p, _Unwind_Word *val)
134
{
135
  unsigned int shift = 0;
136
  unsigned char byte;
137
  _Unwind_Word result;
138
 
139
  result = 0;
140
  do
141
    {
142
      byte = *p++;
143
      result |= ((_Unwind_Word)byte & 0x7f) << shift;
144
      shift += 7;
145
    }
146
  while (byte & 0x80);
147
 
148
  *val = result;
149
  return p;
150
}
151
 
152
/* Similar, but read a signed leb128 value.  */
153
 
154
static const unsigned char *
155
read_sleb128 (const unsigned char *p, _Unwind_Sword *val)
156
{
157
  unsigned int shift = 0;
158
  unsigned char byte;
159
  _Unwind_Word result;
160
 
161
  result = 0;
162
  do
163
    {
164
      byte = *p++;
165
      result |= ((_Unwind_Word)byte & 0x7f) << shift;
166
      shift += 7;
167
    }
168
  while (byte & 0x80);
169
 
170
  /* Sign-extend a negative value.  */
171
  if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
172
    result |= -(((_Unwind_Word)1L) << shift);
173
 
174
  *val = (_Unwind_Sword) result;
175
  return p;
176
}
177
 
178
/* Load an encoded value from memory at P.  The value is returned in VAL;
179
   The function returns P incremented past the value.  BASE is as given
180
   by base_of_encoded_value for this encoding in the appropriate context.  */
181
 
182
static const unsigned char *
183
read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
184
                              const unsigned char *p, _Unwind_Ptr *val)
185
{
186
  union unaligned
187
    {
188
      void *ptr;
189
      unsigned u2 __attribute__ ((mode (HI)));
190
      unsigned u4 __attribute__ ((mode (SI)));
191
      unsigned u8 __attribute__ ((mode (DI)));
192
      signed s2 __attribute__ ((mode (HI)));
193
      signed s4 __attribute__ ((mode (SI)));
194
      signed s8 __attribute__ ((mode (DI)));
195
    } __attribute__((__packed__));
196
 
197
  const union unaligned *u = (const union unaligned *) p;
198
  _Unwind_Internal_Ptr result;
199
 
200
  if (encoding == DW_EH_PE_aligned)
201
    {
202
      _Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
203
      a = (a + sizeof (void *) - 1) & - sizeof(void *);
204
      result = *(_Unwind_Internal_Ptr *) a;
205
      p = (const unsigned char *) (_Unwind_Internal_Ptr) (a + sizeof (void *));
206
    }
207
  else
208
    {
209
      switch (encoding & 0x0f)
210
        {
211
        case DW_EH_PE_absptr:
212
          result = (_Unwind_Internal_Ptr) u->ptr;
213
          p += sizeof (void *);
214
          break;
215
 
216
        case DW_EH_PE_uleb128:
217
          {
218
            _Unwind_Word tmp;
219
            p = read_uleb128 (p, &tmp);
220
            result = (_Unwind_Internal_Ptr) tmp;
221
          }
222
          break;
223
 
224
        case DW_EH_PE_sleb128:
225
          {
226
            _Unwind_Sword tmp;
227
            p = read_sleb128 (p, &tmp);
228
            result = (_Unwind_Internal_Ptr) tmp;
229
          }
230
          break;
231
 
232
        case DW_EH_PE_udata2:
233
          result = u->u2;
234
          p += 2;
235
          break;
236
        case DW_EH_PE_udata4:
237
          result = u->u4;
238
          p += 4;
239
          break;
240
        case DW_EH_PE_udata8:
241
          result = u->u8;
242
          p += 8;
243
          break;
244
 
245
        case DW_EH_PE_sdata2:
246
          result = u->s2;
247
          p += 2;
248
          break;
249
        case DW_EH_PE_sdata4:
250
          result = u->s4;
251
          p += 4;
252
          break;
253
        case DW_EH_PE_sdata8:
254
          result = u->s8;
255
          p += 8;
256
          break;
257
 
258
        default:
259
          __gxx_abort ();
260
        }
261
 
262
      if (result != 0)
263
        {
264
          result += ((encoding & 0x70) == DW_EH_PE_pcrel
265
                     ? (_Unwind_Internal_Ptr) u : base);
266
          if (encoding & DW_EH_PE_indirect)
267
            result = *(_Unwind_Internal_Ptr *) result;
268
        }
269
    }
270
 
271
  *val = result;
272
  return p;
273
}
274
 
275
#ifndef NO_BASE_OF_ENCODED_VALUE
276
 
277
/* Like read_encoded_value_with_base, but get the base from the context
278
   rather than providing it directly.  */
279
 
280
static inline const unsigned char *
281
read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
282
                    const unsigned char *p, _Unwind_Ptr *val)
283
{
284
  return read_encoded_value_with_base (encoding,
285
                base_of_encoded_value (encoding, context),
286
                p, val);
287
}
288
 
289
#endif
290
 
291
#endif /* unwind-pe.h */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.