Coverage Report

Created: 2025-07-11 07:01

/src/libunwind/include/dwarf_i.h
Line
Count
Source (jump to first uncovered line)
1
#ifndef DWARF_I_H
2
#define DWARF_I_H
3
4
/* This file contains definitions that cannot be used in code outside
5
   of libunwind.  In particular, most inline functions are here
6
   because otherwise they'd generate unresolved references when the
7
   files are compiled with inlining disabled.  */
8
9
#include "dwarf.h"
10
#include "libunwind_i.h"
11
12
/* Unless we are told otherwise, assume that a "machine address" is
13
   the size of an unw_word_t.  */
14
#ifndef dwarf_addr_size
15
75
# define dwarf_addr_size(as) (sizeof (unw_word_t))
16
#endif
17
18
#ifndef dwarf_to_unw_regnum
19
48.0k
# define dwarf_to_unw_regnum_map                UNW_OBJ (dwarf_to_unw_regnum_map)
20
extern const uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH];
21
/* REG is evaluated multiple times; it better be side-effects free!  */
22
# define dwarf_to_unw_regnum(reg)                                         \
23
48.0k
  (((reg) < DWARF_REGNUM_MAP_LENGTH) ? dwarf_to_unw_regnum_map[reg] : 0)
24
#endif
25
26
#ifdef UNW_LOCAL_ONLY
27
28
/* In the local-only case, we can let the compiler directly access
29
   memory and don't need to worry about differing byte-order.  */
30
31
typedef union __attribute__ ((packed))
32
  {
33
    int8_t s8;
34
    int16_t s16;
35
    int32_t s32;
36
    int64_t s64;
37
    uint8_t u8;
38
    uint16_t u16;
39
    uint32_t u32;
40
    uint64_t u64;
41
    void *ptr;
42
  }
43
dwarf_misaligned_value_t;
44
45
static inline int
46
dwarf_reads8 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr,
47
              int8_t *val, void *arg UNUSED)
48
0
{
49
0
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
50
0
51
0
  *val = mvp->s8;
52
0
  *addr += sizeof (mvp->s8);
53
0
  return 0;
54
0
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_reads8
Unexecuted instantiation: Lglobal.c:dwarf_reads8
Unexecuted instantiation: Lparser.c:dwarf_reads8
Unexecuted instantiation: Lpe.c:dwarf_reads8
Unexecuted instantiation: Lexpr.c:dwarf_reads8
Unexecuted instantiation: Lfde.c:dwarf_reads8
55
56
static inline int
57
dwarf_reads16 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr,
58
               int16_t *val, void *arg UNUSED)
59
0
{
60
0
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
61
62
0
  *val = mvp->s16;
63
0
  *addr += sizeof (mvp->s16);
64
0
  return 0;
65
0
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_reads16
Unexecuted instantiation: Lglobal.c:dwarf_reads16
Unexecuted instantiation: Lparser.c:dwarf_reads16
Unexecuted instantiation: Lpe.c:dwarf_reads16
Unexecuted instantiation: Lexpr.c:dwarf_reads16
Unexecuted instantiation: Lfde.c:dwarf_reads16
66
67
static inline int
68
dwarf_reads32 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr,
69
               int32_t *val, void *arg UNUSED)
70
60
{
71
60
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
72
73
60
  *val = mvp->s32;
74
60
  *addr += sizeof (mvp->s32);
75
60
  return 0;
76
60
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_reads32
Unexecuted instantiation: Lglobal.c:dwarf_reads32
Unexecuted instantiation: Lparser.c:dwarf_reads32
Lpe.c:dwarf_reads32
Line
Count
Source
70
45
{
71
45
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
72
73
45
  *val = mvp->s32;
74
45
  *addr += sizeof (mvp->s32);
75
45
  return 0;
76
45
}
Unexecuted instantiation: Lexpr.c:dwarf_reads32
Lfde.c:dwarf_reads32
Line
Count
Source
70
15
{
71
15
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
72
73
15
  *val = mvp->s32;
74
15
  *addr += sizeof (mvp->s32);
75
15
  return 0;
76
15
}
77
78
static inline int
79
dwarf_reads64 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr,
80
               int64_t *val, void *arg UNUSED)
81
0
{
82
0
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
83
84
0
  *val = mvp->s64;
85
0
  *addr += sizeof (mvp->s64);
86
0
  return 0;
87
0
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_reads64
Unexecuted instantiation: Lglobal.c:dwarf_reads64
Unexecuted instantiation: Lparser.c:dwarf_reads64
Unexecuted instantiation: Lpe.c:dwarf_reads64
Unexecuted instantiation: Lexpr.c:dwarf_reads64
Unexecuted instantiation: Lfde.c:dwarf_reads64
88
89
static inline int
90
dwarf_readu8 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr,
91
              uint8_t *val, void *arg UNUSED)
92
520
{
93
520
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
94
95
520
  *val = mvp->u8;
96
520
  *addr += sizeof (mvp->u8);
97
520
  return 0;
98
520
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_readu8
Unexecuted instantiation: Lglobal.c:dwarf_readu8
Lparser.c:dwarf_readu8
Line
Count
Source
92
370
{
93
370
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
94
95
370
  *val = mvp->u8;
96
370
  *addr += sizeof (mvp->u8);
97
370
  return 0;
98
370
}
Unexecuted instantiation: Lpe.c:dwarf_readu8
Unexecuted instantiation: Lexpr.c:dwarf_readu8
Lfde.c:dwarf_readu8
Line
Count
Source
92
150
{
93
150
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
94
95
150
  *val = mvp->u8;
96
150
  *addr += sizeof (mvp->u8);
97
150
  return 0;
98
150
}
99
100
static inline int
101
dwarf_readu16 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr,
102
               uint16_t *val, void *arg UNUSED)
103
7
{
104
7
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
105
106
7
  *val = mvp->u16;
107
7
  *addr += sizeof (mvp->u16);
108
7
  return 0;
109
7
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_readu16
Unexecuted instantiation: Lglobal.c:dwarf_readu16
Lparser.c:dwarf_readu16
Line
Count
Source
103
7
{
104
7
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
105
106
7
  *val = mvp->u16;
107
7
  *addr += sizeof (mvp->u16);
108
7
  return 0;
109
7
}
Unexecuted instantiation: Lpe.c:dwarf_readu16
Unexecuted instantiation: Lexpr.c:dwarf_readu16
Unexecuted instantiation: Lfde.c:dwarf_readu16
110
111
static inline int
112
dwarf_readu32 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr,
113
               uint32_t *val, void *arg UNUSED)
114
60
{
115
60
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
116
117
60
  *val = mvp->u32;
118
60
  *addr += sizeof (mvp->u32);
119
60
  return 0;
120
60
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_readu32
Unexecuted instantiation: Lglobal.c:dwarf_readu32
Unexecuted instantiation: Lparser.c:dwarf_readu32
Lpe.c:dwarf_readu32
Line
Count
Source
114
15
{
115
15
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
116
117
15
  *val = mvp->u32;
118
15
  *addr += sizeof (mvp->u32);
119
15
  return 0;
120
15
}
Unexecuted instantiation: Lexpr.c:dwarf_readu32
Lfde.c:dwarf_readu32
Line
Count
Source
114
45
{
115
45
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
116
117
45
  *val = mvp->u32;
118
45
  *addr += sizeof (mvp->u32);
119
45
  return 0;
120
45
}
121
122
static inline int
123
dwarf_readu64 (unw_addr_space_t as UNUSED, unw_accessors_t *a UNUSED, unw_word_t *addr,
124
               uint64_t *val, void *arg UNUSED)
125
0
{
126
0
  dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
127
128
0
  *val = mvp->u64;
129
0
  *addr += sizeof (mvp->u64);
130
0
  return 0;
131
0
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_readu64
Unexecuted instantiation: Lglobal.c:dwarf_readu64
Unexecuted instantiation: Lparser.c:dwarf_readu64
Unexecuted instantiation: Lpe.c:dwarf_readu64
Unexecuted instantiation: Lexpr.c:dwarf_readu64
Unexecuted instantiation: Lfde.c:dwarf_readu64
132
133
#else /* !UNW_LOCAL_ONLY */
134
135
static inline int
136
dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
137
              uint8_t *valp, void *arg)
138
0
{
139
0
  unw_word_t val, aligned_addr = *addr & (~sizeof (unw_word_t) + 1);
140
0
  unw_word_t off = *addr - aligned_addr;
141
0
  int ret;
142
0
143
0
  *addr += 1;
144
0
  ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
145
0
#if UNW_BYTE_ORDER == UNW_LITTLE_ENDIAN
146
0
  val >>= 8*off;
147
0
#else
148
0
  val >>= 8*(sizeof (unw_word_t) - 1 - off);
149
0
#endif
150
0
  *valp = (uint8_t) val;
151
0
  return ret;
152
0
}
153
154
static inline int
155
dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
156
               uint16_t *val, void *arg)
157
0
{
158
0
  uint8_t v0, v1;
159
0
  int ret;
160
0
161
0
  if ((ret = dwarf_readu8 (as, a, addr, &v0, arg)) < 0
162
0
      || (ret = dwarf_readu8 (as, a, addr, &v1, arg)) < 0)
163
0
    return ret;
164
0
165
0
  if (tdep_big_endian (as))
166
0
    *val = (uint16_t) v0 << 8 | v1;
167
0
  else
168
0
    *val = (uint16_t) v1 << 8 | v0;
169
0
  return 0;
170
0
}
171
172
static inline int
173
dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
174
               uint32_t *val, void *arg)
175
0
{
176
0
  uint16_t v0, v1;
177
0
  int ret;
178
0
179
0
  if ((ret = dwarf_readu16 (as, a, addr, &v0, arg)) < 0
180
0
      || (ret = dwarf_readu16 (as, a, addr, &v1, arg)) < 0)
181
0
    return ret;
182
0
183
0
  if (tdep_big_endian (as))
184
0
    *val = (uint32_t) v0 << 16 | v1;
185
0
  else
186
0
    *val = (uint32_t) v1 << 16 | v0;
187
0
  return 0;
188
0
}
189
190
static inline int
191
dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
192
               uint64_t *val, void *arg)
193
0
{
194
0
  uint32_t v0, v1;
195
0
  int ret;
196
0
197
0
  if ((ret = dwarf_readu32 (as, a, addr, &v0, arg)) < 0
198
0
      || (ret = dwarf_readu32 (as, a, addr, &v1, arg)) < 0)
199
0
    return ret;
200
0
201
0
  if (tdep_big_endian (as))
202
0
    *val = (uint64_t) v0 << 32 | v1;
203
0
  else
204
0
    *val = (uint64_t) v1 << 32 | v0;
205
0
  return 0;
206
0
}
207
208
static inline int
209
dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
210
              int8_t *val, void *arg)
211
0
{
212
0
  uint8_t uval;
213
0
  int ret;
214
0
215
0
  if ((ret = dwarf_readu8 (as, a, addr, &uval, arg)) < 0)
216
0
    return ret;
217
0
  *val = (int8_t) uval;
218
0
  return 0;
219
0
}
220
221
static inline int
222
dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
223
               int16_t *val, void *arg)
224
0
{
225
0
  uint16_t uval;
226
0
  int ret;
227
0
228
0
  if ((ret = dwarf_readu16 (as, a, addr, &uval, arg)) < 0)
229
0
    return ret;
230
0
  *val = (int16_t) uval;
231
0
  return 0;
232
0
}
233
234
static inline int
235
dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
236
               int32_t *val, void *arg)
237
0
{
238
0
  uint32_t uval;
239
0
  int ret;
240
0
241
0
  if ((ret = dwarf_readu32 (as, a, addr, &uval, arg)) < 0)
242
0
    return ret;
243
0
  *val = (int32_t) uval;
244
0
  return 0;
245
0
}
246
247
static inline int
248
dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
249
               int64_t *val, void *arg)
250
0
{
251
0
  uint64_t uval;
252
0
  int ret;
253
0
254
0
  if ((ret = dwarf_readu64 (as, a, addr, &uval, arg)) < 0)
255
0
    return ret;
256
0
  *val = (int64_t) uval;
257
0
  return 0;
258
0
}
259
260
#endif /* !UNW_LOCAL_ONLY */
261
262
static inline int
263
dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
264
             unw_word_t *val, void *arg)
265
0
{
266
0
  uint32_t u32;
267
0
  uint64_t u64;
268
0
  int ret;
269
270
0
  switch (dwarf_addr_size (as))
271
0
    {
272
0
    case 4:
273
0
      ret = dwarf_readu32 (as, a, addr, &u32, arg);
274
0
      if (ret < 0)
275
0
        return ret;
276
0
      *val = u32;
277
0
      return ret;
278
279
0
    case 8:
280
0
      ret = dwarf_readu64 (as, a, addr, &u64, arg);
281
0
      if (ret < 0)
282
0
        return ret;
283
0
      *val = (unw_word_t) u64;
284
0
      return ret;
285
286
0
    default:
287
0
      abort ();
288
0
    }
289
0
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_readw
Unexecuted instantiation: Lglobal.c:dwarf_readw
Unexecuted instantiation: Lparser.c:dwarf_readw
Unexecuted instantiation: Lpe.c:dwarf_readw
Unexecuted instantiation: global.c:dwarf_readw
Unexecuted instantiation: Lexpr.c:dwarf_readw
Unexecuted instantiation: Lfde.c:dwarf_readw
290
291
/* Read an unsigned "little-endian base 128" value.  See Chapter 7.6
292
   of DWARF spec v3.  */
293
294
static inline int
295
dwarf_read_uleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
296
                    unw_word_t *valp, void *arg)
297
187
{
298
187
  unw_word_t val = 0, shift = 0;
299
187
  unsigned char byte;
300
187
  int ret;
301
302
187
  do
303
188
    {
304
188
      if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
305
0
        return ret;
306
307
188
      val |= ((unw_word_t) byte & 0x7f) << shift;
308
188
      shift += 7;
309
188
    }
310
188
  while (byte & 0x80);
311
312
187
  *valp = val;
313
187
  return 0;
314
187
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_read_uleb128
Unexecuted instantiation: Lglobal.c:dwarf_read_uleb128
Lparser.c:dwarf_read_uleb128
Line
Count
Source
297
142
{
298
142
  unw_word_t val = 0, shift = 0;
299
142
  unsigned char byte;
300
142
  int ret;
301
302
142
  do
303
143
    {
304
143
      if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
305
0
        return ret;
306
307
143
      val |= ((unw_word_t) byte & 0x7f) << shift;
308
143
      shift += 7;
309
143
    }
310
143
  while (byte & 0x80);
311
312
142
  *valp = val;
313
142
  return 0;
314
142
}
Unexecuted instantiation: Lpe.c:dwarf_read_uleb128
Unexecuted instantiation: global.c:dwarf_read_uleb128
Unexecuted instantiation: Lexpr.c:dwarf_read_uleb128
Lfde.c:dwarf_read_uleb128
Line
Count
Source
297
45
{
298
45
  unw_word_t val = 0, shift = 0;
299
45
  unsigned char byte;
300
45
  int ret;
301
302
45
  do
303
45
    {
304
45
      if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
305
0
        return ret;
306
307
45
      val |= ((unw_word_t) byte & 0x7f) << shift;
308
45
      shift += 7;
309
45
    }
310
45
  while (byte & 0x80);
311
312
45
  *valp = val;
313
45
  return 0;
314
45
}
315
316
/* Read a signed "little-endian base 128" value.  See Chapter 7.6 of
317
   DWARF spec v3.  */
318
319
static inline int
320
dwarf_read_sleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
321
                    unw_word_t *valp, void *arg)
322
15
{
323
15
  unw_word_t val = 0, shift = 0;
324
15
  unsigned char byte;
325
15
  int ret;
326
327
15
  do
328
15
    {
329
15
      if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
330
0
        return ret;
331
332
15
      val |= ((unw_word_t) byte & 0x7f) << shift;
333
15
      shift += 7;
334
15
    }
335
15
  while (byte & 0x80);
336
337
15
  if (shift < 8 * sizeof (unw_word_t) && (byte & 0x40) != 0)
338
    /* sign-extend negative value */
339
15
    val |= ((unw_word_t) -1) << shift;
340
341
15
  *valp = val;
342
15
  return 0;
343
15
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_read_sleb128
Unexecuted instantiation: Lglobal.c:dwarf_read_sleb128
Unexecuted instantiation: Lparser.c:dwarf_read_sleb128
Unexecuted instantiation: Lpe.c:dwarf_read_sleb128
Unexecuted instantiation: global.c:dwarf_read_sleb128
Unexecuted instantiation: Lexpr.c:dwarf_read_sleb128
Lfde.c:dwarf_read_sleb128
Line
Count
Source
322
15
{
323
15
  unw_word_t val = 0, shift = 0;
324
15
  unsigned char byte;
325
15
  int ret;
326
327
15
  do
328
15
    {
329
15
      if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
330
0
        return ret;
331
332
15
      val |= ((unw_word_t) byte & 0x7f) << shift;
333
15
      shift += 7;
334
15
    }
335
15
  while (byte & 0x80);
336
337
15
  if (shift < 8 * sizeof (unw_word_t) && (byte & 0x40) != 0)
338
    /* sign-extend negative value */
339
15
    val |= ((unw_word_t) -1) << shift;
340
341
15
  *valp = val;
342
15
  return 0;
343
15
}
344
345
static ALWAYS_INLINE int
346
dwarf_read_encoded_pointer_inlined (unw_addr_space_t as, unw_accessors_t *a,
347
                                    unw_word_t *addr, unsigned char encoding,
348
                                    const unw_proc_info_t *pi,
349
                                    unw_word_t *valp, void *arg)
350
75
{
351
75
  unw_word_t val, initial_addr = *addr;
352
75
  uint16_t uval16;
353
75
  uint32_t uval32;
354
75
  uint64_t uval64;
355
75
  int16_t sval16 = 0;
356
75
  int32_t sval32 = 0;
357
75
  int64_t sval64 = 0;
358
75
  int ret;
359
360
  /* DW_EH_PE_omit and DW_EH_PE_aligned don't follow the normal
361
     format/application encoding.  Handle them first.  */
362
75
  if (encoding == DW_EH_PE_omit)
363
15
    {
364
15
      *valp = 0;
365
15
      return 0;
366
15
    }
367
60
  else if (encoding == DW_EH_PE_aligned)
368
0
    {
369
0
      int size = dwarf_addr_size (as);
370
0
      *addr = (initial_addr + size - 1) & -size;
371
0
      return dwarf_readw (as, a, addr, valp, arg);
372
0
    }
373
374
60
  switch (encoding & DW_EH_PE_FORMAT_MASK)
375
60
    {
376
0
    case DW_EH_PE_ptr:
377
0
      if ((ret = dwarf_readw (as, a, addr, &val, arg)) < 0)
378
0
        return ret;
379
0
      break;
380
381
0
    case DW_EH_PE_uleb128:
382
0
      if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
383
0
        return ret;
384
0
      break;
385
386
0
    case DW_EH_PE_udata2:
387
0
      if ((ret = dwarf_readu16 (as, a, addr, &uval16, arg)) < 0)
388
0
        return ret;
389
0
      val = uval16;
390
0
      break;
391
392
15
    case DW_EH_PE_udata4:
393
15
      if ((ret = dwarf_readu32 (as, a, addr, &uval32, arg)) < 0)
394
0
        return ret;
395
15
      val = uval32;
396
15
      break;
397
398
0
    case DW_EH_PE_udata8:
399
0
      if ((ret = dwarf_readu64 (as, a, addr, &uval64, arg)) < 0)
400
0
        return ret;
401
0
      val = (unw_word_t) uval64;
402
0
      break;
403
404
0
    case DW_EH_PE_sleb128:
405
0
      if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
406
0
        return ret;
407
0
      break;
408
409
0
    case DW_EH_PE_sdata2:
410
0
      if ((ret = dwarf_reads16 (as, a, addr, &sval16, arg)) < 0)
411
0
        return ret;
412
0
      val = sval16;
413
0
      break;
414
415
45
    case DW_EH_PE_sdata4:
416
45
      if ((ret = dwarf_reads32 (as, a, addr, &sval32, arg)) < 0)
417
0
        return ret;
418
45
      val = sval32;
419
45
      break;
420
421
0
    case DW_EH_PE_sdata8:
422
0
      if ((ret = dwarf_reads64 (as, a, addr, &sval64, arg)) < 0)
423
0
        return ret;
424
0
      val = (unw_word_t) sval64;
425
0
      break;
426
427
0
    default:
428
0
      Debug (1, "unexpected encoding format 0x%x\n",
429
0
             encoding & DW_EH_PE_FORMAT_MASK);
430
0
      return -UNW_EINVAL;
431
60
    }
432
433
60
  if (val == 0)
434
0
    {
435
      /* 0 is a special value and always absolute.  */
436
0
      *valp = 0;
437
0
      return 0;
438
0
    }
439
440
60
  switch (encoding & DW_EH_PE_APPL_MASK)
441
60
    {
442
30
    case DW_EH_PE_absptr:
443
30
      break;
444
445
30
    case DW_EH_PE_pcrel:
446
30
      val += initial_addr;
447
30
      break;
448
449
0
    case DW_EH_PE_datarel:
450
      /* XXX For now, assume that data-relative addresses are relative
451
         to the global pointer.  */
452
0
      val += pi->gp;
453
0
      break;
454
455
0
    case DW_EH_PE_funcrel:
456
0
      val += pi->start_ip;
457
0
      break;
458
459
0
    case DW_EH_PE_textrel:
460
      /* XXX For now we don't support text-rel values.  If there is a
461
         platform which needs this, we probably would have to add a
462
         "segbase" member to unw_proc_info_t.  */
463
0
    default:
464
0
      Debug (1, "unexpected application type 0x%x\n",
465
0
             encoding & DW_EH_PE_APPL_MASK);
466
0
      return -UNW_EINVAL;
467
60
    }
468
469
  /* Trim off any extra bits.  Assume that sign extension isn't
470
     required; the only place it is needed is MIPS kernel space
471
     addresses.  */
472
60
  if (sizeof (val) > dwarf_addr_size (as))
473
0
    {
474
0
      assert (dwarf_addr_size (as) == 4);
475
0
      val = (uint32_t) val;
476
0
    }
477
478
60
  if (encoding & DW_EH_PE_indirect)
479
0
    {
480
0
      unw_word_t indirect_addr = val;
481
482
0
      if ((ret = dwarf_readw (as, a, &indirect_addr, &val, arg)) < 0)
483
0
        return ret;
484
0
    }
485
486
60
  *valp = val;
487
60
  return 0;
488
60
}
Unexecuted instantiation: Lfind_proc_info-lsb.c:dwarf_read_encoded_pointer_inlined
Unexecuted instantiation: Lglobal.c:dwarf_read_encoded_pointer_inlined
Unexecuted instantiation: Lparser.c:dwarf_read_encoded_pointer_inlined
Lpe.c:dwarf_read_encoded_pointer_inlined
Line
Count
Source
350
75
{
351
75
  unw_word_t val, initial_addr = *addr;
352
75
  uint16_t uval16;
353
75
  uint32_t uval32;
354
75
  uint64_t uval64;
355
75
  int16_t sval16 = 0;
356
75
  int32_t sval32 = 0;
357
75
  int64_t sval64 = 0;
358
75
  int ret;
359
360
  /* DW_EH_PE_omit and DW_EH_PE_aligned don't follow the normal
361
     format/application encoding.  Handle them first.  */
362
75
  if (encoding == DW_EH_PE_omit)
363
15
    {
364
15
      *valp = 0;
365
15
      return 0;
366
15
    }
367
60
  else if (encoding == DW_EH_PE_aligned)
368
0
    {
369
0
      int size = dwarf_addr_size (as);
370
0
      *addr = (initial_addr + size - 1) & -size;
371
0
      return dwarf_readw (as, a, addr, valp, arg);
372
0
    }
373
374
60
  switch (encoding & DW_EH_PE_FORMAT_MASK)
375
60
    {
376
0
    case DW_EH_PE_ptr:
377
0
      if ((ret = dwarf_readw (as, a, addr, &val, arg)) < 0)
378
0
        return ret;
379
0
      break;
380
381
0
    case DW_EH_PE_uleb128:
382
0
      if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
383
0
        return ret;
384
0
      break;
385
386
0
    case DW_EH_PE_udata2:
387
0
      if ((ret = dwarf_readu16 (as, a, addr, &uval16, arg)) < 0)
388
0
        return ret;
389
0
      val = uval16;
390
0
      break;
391
392
15
    case DW_EH_PE_udata4:
393
15
      if ((ret = dwarf_readu32 (as, a, addr, &uval32, arg)) < 0)
394
0
        return ret;
395
15
      val = uval32;
396
15
      break;
397
398
0
    case DW_EH_PE_udata8:
399
0
      if ((ret = dwarf_readu64 (as, a, addr, &uval64, arg)) < 0)
400
0
        return ret;
401
0
      val = (unw_word_t) uval64;
402
0
      break;
403
404
0
    case DW_EH_PE_sleb128:
405
0
      if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
406
0
        return ret;
407
0
      break;
408
409
0
    case DW_EH_PE_sdata2:
410
0
      if ((ret = dwarf_reads16 (as, a, addr, &sval16, arg)) < 0)
411
0
        return ret;
412
0
      val = sval16;
413
0
      break;
414
415
45
    case DW_EH_PE_sdata4:
416
45
      if ((ret = dwarf_reads32 (as, a, addr, &sval32, arg)) < 0)
417
0
        return ret;
418
45
      val = sval32;
419
45
      break;
420
421
0
    case DW_EH_PE_sdata8:
422
0
      if ((ret = dwarf_reads64 (as, a, addr, &sval64, arg)) < 0)
423
0
        return ret;
424
0
      val = (unw_word_t) sval64;
425
0
      break;
426
427
0
    default:
428
0
      Debug (1, "unexpected encoding format 0x%x\n",
429
0
             encoding & DW_EH_PE_FORMAT_MASK);
430
0
      return -UNW_EINVAL;
431
60
    }
432
433
60
  if (val == 0)
434
0
    {
435
      /* 0 is a special value and always absolute.  */
436
0
      *valp = 0;
437
0
      return 0;
438
0
    }
439
440
60
  switch (encoding & DW_EH_PE_APPL_MASK)
441
60
    {
442
30
    case DW_EH_PE_absptr:
443
30
      break;
444
445
30
    case DW_EH_PE_pcrel:
446
30
      val += initial_addr;
447
30
      break;
448
449
0
    case DW_EH_PE_datarel:
450
      /* XXX For now, assume that data-relative addresses are relative
451
         to the global pointer.  */
452
0
      val += pi->gp;
453
0
      break;
454
455
0
    case DW_EH_PE_funcrel:
456
0
      val += pi->start_ip;
457
0
      break;
458
459
0
    case DW_EH_PE_textrel:
460
      /* XXX For now we don't support text-rel values.  If there is a
461
         platform which needs this, we probably would have to add a
462
         "segbase" member to unw_proc_info_t.  */
463
0
    default:
464
0
      Debug (1, "unexpected application type 0x%x\n",
465
0
             encoding & DW_EH_PE_APPL_MASK);
466
0
      return -UNW_EINVAL;
467
60
    }
468
469
  /* Trim off any extra bits.  Assume that sign extension isn't
470
     required; the only place it is needed is MIPS kernel space
471
     addresses.  */
472
60
  if (sizeof (val) > dwarf_addr_size (as))
473
0
    {
474
0
      assert (dwarf_addr_size (as) == 4);
475
0
      val = (uint32_t) val;
476
0
    }
477
478
60
  if (encoding & DW_EH_PE_indirect)
479
0
    {
480
0
      unw_word_t indirect_addr = val;
481
482
0
      if ((ret = dwarf_readw (as, a, &indirect_addr, &val, arg)) < 0)
483
0
        return ret;
484
0
    }
485
486
60
  *valp = val;
487
60
  return 0;
488
60
}
Unexecuted instantiation: global.c:dwarf_read_encoded_pointer_inlined
Unexecuted instantiation: Lexpr.c:dwarf_read_encoded_pointer_inlined
Unexecuted instantiation: Lfde.c:dwarf_read_encoded_pointer_inlined
489
490
#endif /* DWARF_I_H */