blob: 938f2a2f83bbe8f81bb6caf21fc8cc96258a633b [file] [log] [blame]
hp.com!davidmeb51b422003-12-20 11:43:08 +00001/* libunwind - a platform-independent unwind library
2 Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5This file is part of libunwind.
6
7Permission is hereby granted, free of charge, to any person obtaining
8a copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sublicense, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice shall be
16included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
25
26#ifndef dwarf_h
27#define dwarf_h
28
29#include "internal.h"
30#include "mempool.h"
31
32struct dwarf_cursor; /* forward-declaration */
33
34#include "dwarf-config.h"
35
36/* DWARF expression opcodes. */
37
38typedef enum
39 {
40 DW_OP_addr = 0x03,
41 DW_OP_deref = 0x06,
42 DW_OP_const1u = 0x08,
43 DW_OP_const1s = 0x09,
44 DW_OP_const2u = 0x0a,
45 DW_OP_const2s = 0x0b,
46 DW_OP_const4u = 0x0c,
47 DW_OP_const4s = 0x0d,
48 DW_OP_const8u = 0x0e,
49 DW_OP_const8s = 0x0f,
50 DW_OP_constu = 0x10,
51 DW_OP_consts = 0x11,
52 DW_OP_dup = 0x12,
53 DW_OP_drop = 0x13,
54 DW_OP_over = 0x14,
55 DW_OP_pick = 0x15,
56 DW_OP_swap = 0x16,
57 DW_OP_rot = 0x17,
58 DW_OP_xderef = 0x18,
59 DW_OP_abs = 0x19,
60 DW_OP_and = 0x1a,
61 DW_OP_div = 0x1b,
62 DW_OP_minus = 0x1c,
63 DW_OP_mod = 0x1d,
64 DW_OP_mul = 0x1e,
65 DW_OP_neg = 0x1f,
66 DW_OP_not = 0x20,
67 DW_OP_or = 0x21,
68 DW_OP_plus = 0x22,
69 DW_OP_plus_uconst = 0x23,
70 DW_OP_shl = 0x24,
71 DW_OP_shr = 0x25,
72 DW_OP_shra = 0x26,
73 DW_OP_xor = 0x27,
74 DW_OP_skip = 0x2f,
75 DW_OP_bra = 0x28,
76 DW_OP_eq = 0x29,
77 DW_OP_ge = 0x2a,
78 DW_OP_gt = 0x2b,
79 DW_OP_le = 0x2c,
80 DW_OP_lt = 0x2d,
81 DW_OP_ne = 0x2e,
82 DW_OP_lit0 = 0x30,
83 DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_lit4, DW_OP_lit5,
84 DW_OP_lit6, DW_OP_lit7, DW_OP_lit8, DW_OP_lit9, DW_OP_lit10,
85 DW_OP_lit11, DW_OP_lit12, DW_OP_lit13, DW_OP_lit14, DW_OP_lit15,
86 DW_OP_lit16, DW_OP_lit17, DW_OP_lit18, DW_OP_lit19, DW_OP_lit20,
87 DW_OP_lit21, DW_OP_lit22, DW_OP_lit23, DW_OP_lit24, DW_OP_lit25,
88 DW_OP_lit26, DW_OP_lit27, DW_OP_lit28, DW_OP_lit29, DW_OP_lit30,
89 DW_OP_lit31,
90 DW_OP_reg0 = 0x50,
91 DW_OP_reg1, DW_OP_reg2, DW_OP_reg3, DW_OP_reg4, DW_OP_reg5,
92 DW_OP_reg6, DW_OP_reg7, DW_OP_reg8, DW_OP_reg9, DW_OP_reg10,
93 DW_OP_reg11, DW_OP_reg12, DW_OP_reg13, DW_OP_reg14, DW_OP_reg15,
94 DW_OP_reg16, DW_OP_reg17, DW_OP_reg18, DW_OP_reg19, DW_OP_reg20,
95 DW_OP_reg21, DW_OP_reg22, DW_OP_reg23, DW_OP_reg24, DW_OP_reg25,
96 DW_OP_reg26, DW_OP_reg27, DW_OP_reg28, DW_OP_reg29, DW_OP_reg30,
97 DW_OP_reg31,
98 DW_OP_breg0 = 0x70,
99 DW_OP_breg1, DW_OP_breg2, DW_OP_breg3, DW_OP_breg4, DW_OP_breg5,
100 DW_OP_breg6, DW_OP_breg7, DW_OP_breg8, DW_OP_breg9, DW_OP_breg10,
101 DW_OP_breg11, DW_OP_breg12, DW_OP_breg13, DW_OP_breg14, DW_OP_breg15,
102 DW_OP_breg16, DW_OP_breg17, DW_OP_breg18, DW_OP_breg19, DW_OP_breg20,
103 DW_OP_breg21, DW_OP_breg22, DW_OP_breg23, DW_OP_breg24, DW_OP_breg25,
104 DW_OP_breg26, DW_OP_breg27, DW_OP_breg28, DW_OP_breg29, DW_OP_breg30,
105 DW_OP_breg31,
106 DW_OP_regx = 0x90,
107 DW_OP_fbreg = 0x91,
108 DW_OP_bregx = 0x92,
109 DW_OP_piece = 0x93,
110 DW_OP_deref_size = 0x94,
111 DW_OP_xderef_size = 0x95,
112 DW_OP_nop = 0x96,
113 DW_OP_push_object_address = 0x97,
114 DW_OP_call2 = 0x98,
115 DW_OP_call4 = 0x99,
116 DW_OP_call_ref = 0x9a,
117 DW_OP_lo_user = 0xe0,
118 DW_OP_hi_user = 0xff
119 }
120dwarf_expr_op_t;
121
122#define DWARF_CIE_VERSION 3 /* GCC emits version 1??? */
123
124#define DWARF_CFA_OPCODE_MASK 0xc0
125#define DWARF_CFA_OPERAND_MASK 0x3f
126
127typedef enum
128 {
129 DW_CFA_advance_loc = 0x40,
130 DW_CFA_offset = 0x80,
131 DW_CFA_restore = 0xc0,
132 DW_CFA_nop = 0x00,
133 DW_CFA_set_loc = 0x01,
134 DW_CFA_advance_loc1 = 0x02,
135 DW_CFA_advance_loc2 = 0x03,
136 DW_CFA_advance_loc4 = 0x04,
137 DW_CFA_offset_extended = 0x05,
138 DW_CFA_restore_extended = 0x06,
139 DW_CFA_undefined = 0x07,
140 DW_CFA_same_value = 0x08,
141 DW_CFA_register = 0x09,
142 DW_CFA_remember_state = 0x0a,
143 DW_CFA_restore_state = 0x0b,
144 DW_CFA_def_cfa = 0x0c,
145 DW_CFA_def_cfa_register = 0x0d,
146 DW_CFA_def_cfa_offset = 0x0e,
147 DW_CFA_def_cfa_expression = 0x0f,
148 DW_CFA_CFA_expression = 0x10,
149 DW_CFA_offset_extended_sf = 0x11,
150 DW_CFA_def_cfa_sf = 0x12,
151 DW_CFA_def_cfa_offset_sf = 0x13,
152 DW_CFA_lo_user = 0x1c,
153 DW_CFA_MIPS_advance_loc8 = 0x1d,
154 DW_CFA_GNU_window_save = 0x2d,
155 DW_CFA_GNU_args_size = 0x2e,
156 DW_CFA_GNU_negative_offset_extended = 0x2f,
157 DW_CFA_hi_user = 0x3c
158 }
159dwarf_cfa_t;
160
161/* DWARF Pointer-Encoding (PEs).
162
163 Pointer-Encodings were invented for the GCC exception-handling
164 support for C++, but they represent a rather generic way of
165 describing the format in which an address/pointer is stored and
166 hence we include the definitions here, in the main dwarf.h file.
167 The Pointer-Encoding format is partially documented in Linux Base
168 Spec v1.3 (http://www.linuxbase.org/spec/). The rest is reverse
169 engineered from GCC.
170
171*/
172#define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
173#define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */
174/* Flag bit. If set, the resulting pointer is the address of the word
175 that contains the final address. */
176#define DW_EH_PE_indirect 0x80
177
178/* Pointer-encoding formats: */
179#define DW_EH_PE_omit 0xff
180#define DW_EH_PE_ptr 0x00 /* pointer-sized unsigned value */
181#define DW_EH_PE_uleb128 0x01 /* unsigned LE base-128 value */
182#define DW_EH_PE_udata2 0x02 /* unsigned 16-bit value */
183#define DW_EH_PE_udata4 0x03 /* unsigned 32-bit value */
184#define DW_EH_PE_udata8 0x04 /* unsigned 64-bit value */
185#define DW_EH_PE_sleb128 0x09 /* signed LE base-128 value */
186#define DW_EH_PE_sdata2 0x0a /* signed 16-bit value */
187#define DW_EH_PE_sdata4 0x0b /* signed 32-bit value */
188#define DW_EH_PE_sdata8 0x0c /* signed 64-bit value */
189
190/* Pointer-encoding application: */
191#define DW_EH_PE_absptr 0x00 /* absolute value */
192#define DW_EH_PE_pcrel 0x10 /* rel. to addr. of encoded value */
193#define DW_EH_PE_textrel 0x20 /* text-relative (GCC-specific???) */
194#define DW_EH_PE_datarel 0x30 /* data-relative */
195/* The following are not documented by LSB v1.3, yet they are used by
196 GCC, presumably they aren't documented by LSB since they aren't
197 used on Linux: */
198#define DW_EH_PE_funcrel 0x40 /* start-of-procedure-relative */
199#define DW_EH_PE_aligned 0x50 /* aligned pointer */
200
201extern HIDDEN struct mempool dwarf_reg_state_pool;
202
203#ifdef UNW_LOCAL_ONLY
204
205/* In the local-only case, we can let the compiler directly access
206 memory and don't need to worry about differing byte-order. */
207
208typedef union
209 {
210 int8_t s8;
211 int16_t s16;
212 int32_t s32;
213 int64_t s64;
214 uint8_t u8;
215 uint16_t u16;
216 uint32_t u32;
217 uint64_t u64;
218 unw_word_t w;
219 void *ptr;
220 }
221dwarf_misaligned_value_t __attribute__ ((packed));
222
223static inline int
224dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
225 int8_t *val, void *arg)
226{
227 dwarf_misaligned_value_t *mvp = (void *) *addr;
228
229 *val = mvp->s8;
230 *addr += sizeof (mvp->s8);
231 return 0;
232}
233
234static inline int
235dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
236 int16_t *val, void *arg)
237{
238 dwarf_misaligned_value_t *mvp = (void *) *addr;
239
240 *val = mvp->s16;
241 *addr += sizeof (mvp->s16);
242 return 0;
243}
244
245static inline int
246dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
247 int32_t *val, void *arg)
248{
249 dwarf_misaligned_value_t *mvp = (void *) *addr;
250
251 *val = mvp->s32;
252 *addr += sizeof (mvp->s32);
253 return 0;
254}
255
256static inline int
257dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
258 int64_t *val, void *arg)
259{
260 dwarf_misaligned_value_t *mvp = (void *) *addr;
261
262 *val = mvp->s64;
263 *addr += sizeof (mvp->s64);
264 return 0;
265}
266
267static inline int
268dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
269 uint8_t *val, void *arg)
270{
271 dwarf_misaligned_value_t *mvp = (void *) *addr;
272
273 *val = mvp->u8;
274 *addr += sizeof (mvp->u8);
275 return 0;
276}
277
278static inline int
279dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
280 uint16_t *val, void *arg)
281{
282 dwarf_misaligned_value_t *mvp = (void *) *addr;
283
284 *val = mvp->u16;
285 *addr += sizeof (mvp->u16);
286 return 0;
287}
288
289static inline int
290dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
291 uint32_t *val, void *arg)
292{
293 dwarf_misaligned_value_t *mvp = (void *) *addr;
294
295 *val = mvp->u32;
296 *addr += sizeof (mvp->u32);
297 return 0;
298}
299
300static inline int
301dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
302 uint64_t *val, void *arg)
303{
304 dwarf_misaligned_value_t *mvp = (void *) *addr;
305
306 *val = mvp->u64;
307 *addr += sizeof (mvp->u64);
308 return 0;
309}
310
311static inline int
312dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
313 unw_word_t *val, void *arg)
314{
315 dwarf_misaligned_value_t *mvp = (void *) *addr;
316
317 *val = mvp->w;
318 *addr += sizeof (mvp->w);
319 return 0;
320}
321
322static inline int
323dwarf_readptr (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
324 unw_word_t *val, void *arg)
325{
326 dwarf_misaligned_value_t *mvp = (void *) *addr;
327
328 *val = (unw_word_t) mvp->ptr;
329 *addr += sizeof (mvp->ptr);
330 return 0;
331}
332
333#else /* !UNW_LOCAL_ONLY */
334
335/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
336
337 FIX ME
338
339 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
340
341typedef union
342 {
343 int8_t s8;
344 int16_t s16;
345 int32_t s32;
346 int64_t s64;
347 uint8_t u8;
348 uint16_t u16;
349 uint32_t u32;
350 uint64_t u64;
351 unw_word_t w;
352 void *ptr;
353 }
354dwarf_misaligned_value_t __attribute__ ((packed));
355
356static inline int
357dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
358 int8_t *val, void *arg)
359{
360 dwarf_misaligned_value_t *mvp = (void *) *addr;
361
362 *val = mvp->s8;
363 *addr += sizeof (mvp->s8);
364 return 0;
365}
366
367static inline int
368dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
369 int16_t *val, void *arg)
370{
371 dwarf_misaligned_value_t *mvp = (void *) *addr;
372
373 *val = mvp->s16;
374 *addr += sizeof (mvp->s16);
375 return 0;
376}
377
378static inline int
379dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
380 int32_t *val, void *arg)
381{
382 dwarf_misaligned_value_t *mvp = (void *) *addr;
383
384 *val = mvp->s32;
385 *addr += sizeof (mvp->s32);
386 return 0;
387}
388
389static inline int
390dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
391 int64_t *val, void *arg)
392{
393 dwarf_misaligned_value_t *mvp = (void *) *addr;
394
395 *val = mvp->s64;
396 *addr += sizeof (mvp->s64);
397 return 0;
398}
399
400static inline int
401dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
402 uint8_t *val, void *arg)
403{
404 dwarf_misaligned_value_t *mvp = (void *) *addr;
405
406 *val = mvp->u8;
407 *addr += sizeof (mvp->u8);
408 return 0;
409}
410
411static inline int
412dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
413 uint16_t *val, void *arg)
414{
415 dwarf_misaligned_value_t *mvp = (void *) *addr;
416
417 *val = mvp->u16;
418 *addr += sizeof (mvp->u16);
419 return 0;
420}
421
422static inline int
423dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
424 uint32_t *val, void *arg)
425{
426 dwarf_misaligned_value_t *mvp = (void *) *addr;
427
428 *val = mvp->u32;
429 *addr += sizeof (mvp->u32);
430 return 0;
431}
432
433static inline int
434dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
435 uint64_t *val, void *arg)
436{
437 dwarf_misaligned_value_t *mvp = (void *) *addr;
438
439 *val = mvp->u64;
440 *addr += sizeof (mvp->u64);
441 return 0;
442}
443
444static inline int
445dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
446 unw_word_t *val, void *arg)
447{
448 dwarf_misaligned_value_t *mvp = (void *) *addr;
449
450 *val = mvp->w;
451 *addr += sizeof (mvp->w);
452 return 0;
453}
454
455static inline int
456dwarf_readptr (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
457 unw_word_t *val, void *arg)
458{
459 dwarf_misaligned_value_t *mvp = (void *) *addr;
460
461 *val = (unw_word_t) mvp->ptr;
462 *addr += sizeof (mvp->ptr);
463 return 0;
464}
465
466#endif /* !UNW_LOCAL_ONLY */
467
468/* Read an unsigned "little-endian base 128" value. See Chapter 7.6
469 of DWARF spec v3. */
470
471static inline int
472dwarf_read_uleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
473 unw_word_t *valp, void *arg)
474{
475 unw_word_t val = 0, shift = 0;
476 unsigned char byte;
477 int ret;
478
479 do
480 {
481 if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
482 return ret;
483
484 val |= ((unw_word_t) byte & 0x7f) << shift;
485 shift += 7;
486 }
487 while (byte & 0x80);
488
489 *valp = val;
490 return 0;
491}
492
493/* Read a signed "little-endian base 128" value. See Chapter 7.6 of
494 DWARF spec v3. */
495
496static inline int
497dwarf_read_sleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
498 unw_word_t *valp, void *arg)
499{
500 unw_word_t val = 0, shift = 0;
501 unsigned char byte;
502 int ret;
503
504 do
505 {
506 if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
507 return ret;
508
509 val |= ((unw_word_t) byte & 0x7f) << shift;
510 shift += 7;
511 }
512 while (byte & 0x80);
513
514 if (shift < 8 * sizeof (unw_word_t) && (byte & 0x40) != 0)
515 /* sign-extend negative value */
516 val |= ((unw_word_t) -1) << shift;
517
518 *valp = val;
519 return 0;
520}
521
522typedef enum
523 {
524 DWARF_WHERE_UNDEF, /* register isn't saved at all */
525 DWARF_WHERE_SAME, /* register has same value as in prev. frame */
526 DWARF_WHERE_CFAREL, /* register saved at CFA-relative address */
527 DWARF_WHERE_REG, /* register saved in another register */
528 DWARF_WHERE_EXPR, /* register saved */
529 }
530dwarf_where_t;
531
532typedef struct
533 {
534 dwarf_where_t where; /* how is the register saved? */
535 unw_word_t val; /* where it's saved */
536 }
537dwarf_save_loc_t;
538
539/* For uniformity, we'd like to treat the CFA save-location like any
540 other register save-location, but this doesn't quite work, because
541 the CFA can be expressed as a (REGISTER,OFFSET) pair. To handle
542 this, we use two dwarf_save_loc structures to describe the CFA.
543 The first one (CFA_REG_COLUMN), tells us where the CFA is saved.
544 In the case of DWARF_WHERE_EXPR, the CFA is defined by a DWARF
545 location expression whose address is given by member "val". In the
546 case of DWARF_WHERE_REG, member "val" gives the number of the
547 base-register and the "val" member of DWARF_CFA_OFF_COLUMN gives
548 the offset value. */
549#define DWARF_CFA_REG_COLUMN DWARF_NUM_PRESERVED_REGS
550#define DWARF_CFA_OFF_COLUMN (DWARF_NUM_PRESERVED_REGS + 1)
551
552typedef struct dwarf_reg_state
553 {
554 struct dwarf_reg_state *next; /* for rs_stack */
555 dwarf_save_loc_t reg[DWARF_NUM_PRESERVED_REGS + 2];
556 }
557dwarf_reg_state_t;
558
559typedef struct dwarf_state_record
560 {
561 unsigned char fde_encoding;
562 unw_word_t args_size;
563
564 dwarf_reg_state_t rs_initial; /* reg-state after CIE instructions */
565 dwarf_reg_state_t rs_current; /* current reg-state */
566 }
567dwarf_state_record_t;
568
569typedef struct dwarf_cursor
570 {
571 void *as_arg; /* argument to address-space callbacks */
572 unw_addr_space_t as; /* reference to per-address-space info */
573
574 unw_word_t cfa; /* canonical frame address; aka frame-/stack-pointer */
575 unw_word_t ip; /* instruction pointer */
576 unw_word_t args_size; /* size of arguments */
577 unw_word_t ret_addr_column; /* column for return-address */
578
579 dwarf_loc_t loc[DWARF_NUM_PRESERVED_REGS];
580
581 unsigned int pi_valid :1; /* is proc_info valid? */
582 unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */
583 unw_proc_info_t pi; /* info about current procedure */
584 }
585dwarf_cursor_t;
586
587/* Convenience macros: */
588#define dwarf_init UNW_ARCH_OBJ (dwarf_init)
589#define dwarf_find_proc_info UNW_OBJ (dwarf_find_proc_info)
590#define dwarf_search_unwind_table UNW_OBJ (dwarf_search_unwind_table)
591#define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
592#define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
593#define dwarf_eval_expr UNW_OBJ (dwarf_eval_expr)
594#define dwarf_parse_fde UNW_OBJ (dwarf_parse_fde)
595#define dwarf_find_save_locs UNW_OBJ (dwarf_find_save_locs)
596#define dwarf_create_state_record UNW_OBJ (dwarf_create_state_record)
597#define dwarf_make_proc_info UNW_OBJ (dwarf_make_proc_info)
598#define dwarf_read_encoded_pointer UNW_OBJ (dwarf_read_encoded_pointer)
599#define dwarf_step UNW_OBJ (dwarf_step)
600
601extern HIDDEN int dwarf_init (void);
602extern HIDDEN int dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
603 unw_proc_info_t *pi,
604 int need_unwind_info, void *arg);
605extern HIDDEN int dwarf_search_unwind_table (unw_addr_space_t as,
606 unw_word_t ip,
607 unw_dyn_info_t *di,
608 unw_proc_info_t *pi,
609 int need_unwind_info, void *arg);
610extern HIDDEN void dwarf_put_unwind_info (unw_addr_space_t as,
611 unw_proc_info_t *pi, void *arg);
612extern HIDDEN int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr,
613 unw_word_t len, unw_word_t *valp,
614 int *is_register);
615extern HIDDEN int dwarf_parse_fde (unw_addr_space_t as, unw_accessors_t *a,
616 unw_word_t *addr, unw_proc_info_t *pi,
617 unw_dyn_dwarf_fde_info_t *dfi, void *arg);
618extern HIDDEN int dwarf_find_save_locs (struct dwarf_cursor *c);
619extern HIDDEN int dwarf_create_state_record (struct dwarf_cursor *c,
620 dwarf_state_record_t *sr);
621extern HIDDEN int dwarf_make_proc_info (struct dwarf_cursor *c);
622extern HIDDEN int dwarf_read_encoded_pointer (unw_addr_space_t as,
623 unw_accessors_t *a,
624 unw_word_t *addr,
625 unsigned char encoding,
626 unw_proc_info_t *pi,
627 unw_word_t *valp, void *arg);
628extern HIDDEN int dwarf_step (struct dwarf_cursor *c);
629
630#endif /* dwarf_h */