1 /* libunwind - a platform-independent unwind library
2 Copyright (C) 2001-2005 Hewlett-Packard Co
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5 This file is several parts of libunwind concatenated.
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
25
26 /* This files contains libunwind-internal definitions which are
27 subject to frequent change and are not to be exposed to
28 libunwind-users. */
29
30 #ifndef libunwind_i_h
31 #define libunwind_i_h
32
33 #ifdef HAVE___THREAD
34 /* For now, turn off per-thread caching. It uses up too much TLS
35 memory per thread even when the thread never uses libunwind at
36 all. */
37 # undef HAVE___THREAD
38 #endif
39
40 /* Platform-independent libunwind-internal declarations. */
41
42 #include <sys/types.h> /* HP-UX needs this before include of pthread.h */
43
44 #include <assert.h>
45 #include "libunwind.h"
46 #include <signal.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <unistd.h>
50
51 #ifdef __GNUC__
52 # define UNUSED __attribute__((unused))
53 # define NORETURN __attribute__((noreturn))
54 # define ALIAS(name) __attribute__((alias (#name)))
55 # if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
56 # define ALWAYS_INLINE inline __attribute__((always_inline))
57 # define HIDDEN __attribute__((visibility ("hidden")))
58 # define PROTECTED __attribute__((visibility ("protected")))
59 # else
60 # define ALWAYS_INLINE
61 # define HIDDEN
62 # define PROTECTED
63 # endif
64 # if (__GNUC__ >= 3)
65 # define likely(x) __builtin_expect ((x), 1)
66 # define unlikely(x) __builtin_expect ((x), 0)
67 # else
68 # define likely(x) (x)
69 # define unlikely(x) (x)
70 # endif
71 #else
72 # define ALWAYS_INLINE
73 # define UNUSED
74 # define NORETURN
75 # define ALIAS(name)
76 # define HIDDEN
77 # define PROTECTED
78 # define likely(x) (x)
79 # define unlikely(x) (x)
80 #endif
81
82 #undef HIDDEN
83 #define HIDDEN static
84
85 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
86
87 #define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
88 #define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
89
90 #ifndef UW_NO_SYNC
91
92 /* Make it easy to write thread-safe code which may or may not be
93 linked against libpthread. The macros below can be used
94 unconditionally and if -lpthread is around, they'll call the
95 corresponding routines otherwise, they do nothing. */
96
97 #pragma weak pthread_mutex_init
98 #pragma weak pthread_mutex_lock
99 #pragma weak pthread_mutex_unlock
100
101 #define mutex_init(l) \
102 (pthread_mutex_init != 0 ? pthread_mutex_init ((l), 0) : 0)
103 #define mutex_lock(l) \
104 (pthread_mutex_lock != 0 ? pthread_mutex_lock (l) : 0)
105 #define mutex_unlock(l) \
106 (pthread_mutex_unlock != 0 ? pthread_mutex_unlock (l) : 0)
107
108 #ifdef HAVE_ATOMIC_OPS_H
109 # include <atomic_ops.h>
110 static inline int
cmpxchg_ptr(void * addr,void * old,void * new)111 cmpxchg_ptr (void *addr, void *old, void *new)
112 {
113 union
114 {
115 void *vp;
116 AO_t *aop;
117 }
118 u;
119
120 u.vp = addr;
121 return AO_compare_and_swap(u.aop, (AO_t) old, (AO_t) new);
122 }
123 # define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr)
124 /* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */
125 # if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
126 # define HAVE_CMPXCHG
127 # endif
128 # define HAVE_FETCH_AND_ADD1
129 #else
130 # ifdef HAVE_IA64INTRIN_H
131 # include <ia64intrin.h>
132 static inline int
cmpxchg_ptr(void * addr,void * old,void * new)133 cmpxchg_ptr (void *addr, void *old, void *new)
134 {
135 union
136 {
137 void *vp;
138 long *vlp;
139 }
140 u;
141
142 u.vp = addr;
143 return __sync_bool_compare_and_swap(u.vlp, (long) old, (long) new);
144 }
145 # define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1)
146 # define HAVE_CMPXCHG
147 # define HAVE_FETCH_AND_ADD1
148 # endif
149 #endif
150 #define atomic_read(ptr) (*(ptr))
151
152 #define unwi_full_mask UNWI_ARCH_OBJ(full_mask)
153
154 /* Type of a mask that can be used to inhibit preemption. At the
155 userlevel, preemption is caused by signals and hence sigset_t is
156 appropriate. In constrast, the Linux kernel uses "unsigned long"
157 to hold the processor "flags" instead. */
158 typedef sigset_t intrmask_t;
159
160 extern intrmask_t unwi_full_mask;
161
162 #define define_lock(name) \
163 pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
164 #define lock_init(l) mutex_init (l)
165 #define lock_acquire(l,m) \
166 do { \
167 sigprocmask (SIG_SETMASK, &unwi_full_mask, &(m)); \
168 mutex_lock (l); \
169 } while (0)
170 #define lock_release(l,m) \
171 do { \
172 mutex_unlock (l); \
173 sigprocmask (SIG_SETMASK, &(m), NULL); \
174 } while (0)
175
176 #else /* UW_NO_SYNC */
177 # define atomic_read(ptr) (*(ptr))
178 typedef int intrmask_t;
179 #endif /* UW_NO_SYNC */
180
181 #define GET_MEMORY(mem, size_in_bytes) \
182 do { \
183 /* Hopefully, mmap() goes straight through to a system call stub... */ \
184 mem = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, \
185 -1, 0); \
186 if (mem == MAP_FAILED) \
187 mem = NULL; \
188 } while (0)
189
190 #define UNW_DEBUG 0
191 #if UNW_DEBUG
192 #define unwi_debug_level UNWI_ARCH_OBJ(debug_level)
193 extern int unwi_debug_level;
194
195 # include <stdio.h>
196 # define Debug(level,format...) \
197 do { \
198 if (unwi_debug_level >= level) \
199 { \
200 int _n = level; \
201 if (_n > 16) \
202 _n = 16; \
203 fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \
204 fprintf (stderr, format); \
205 } \
206 } while (0)
207 # define Dprintf(format...) fprintf (stderr, format)
208 # ifdef __GNUC__
209 # undef inline
210 # define inline UNUSED
211 # endif
212 #else
213 # define Debug(level,format...)
214 # define Dprintf(format...)
215 #endif
216
217 static ALWAYS_INLINE int
print_error(const char * string)218 print_error (const char *string)
219 {
220 return write (2, string, strlen (string));
221 }
222
223 #define mi_init UNWI_ARCH_OBJ(mi_init)
224
225 extern void mi_init (void); /* machine-independent initializations */
226 extern unw_word_t _U_dyn_info_list_addr (void);
227
228 /* This is needed/used by ELF targets only. */
229
230 struct elf_image
231 {
232 void *image; /* pointer to mmap'd image */
233 size_t size; /* (file-) size of the image */
234 };
235
236 /* Target-dependent definitions that are internal to libunwind but need
237 to be shared with target-independent code. */
238
239 /*XXXXXXXXXXXXXXXXXXXXXXXXX Start unwind_dl.h XXXXXXXXXXXXXXXXXXXXXXXXXX*/
240
241 #ifdef OS_X
242
243 #define elf_w(x) x
244 #define Elf_W(x) x
245
246 #include <mach-o/loader.h>
247 #include <mach-o/dyld.h>
248
249 #define PT_LOAD LC_SEGMENT
250 #define PT_GNU_EH_FRAME -1
251 #define PT_DYNAMIC -1
252
253 #define DT_NULL 0
254 #define DT_PLTGOT 1
255
256 #define DW_EH_VERSION 1
257
258 typedef long Addr;
259 typedef struct {
260 long p_type;
261 Addr p_vaddr;
262 long p_memsz;
263 long p_filesz;
264 } Phdr;
265
266 typedef struct {
267 long d_tag;
268 struct { long d_ptr; } d_un;
269 } Dyn;
270
271 struct dl_phdr_info {
272 Phdr *dlpi_phdr;
273 Addr dlpi_addr;
274 long dlpi_phnum;
275 char *dlpi_name;
276 };
277
278 typedef int (*DL_Iter_Callback)(struct dl_phdr_info *info, size_t size, void *ptr);
279 int dl_iterate_phdr (DL_Iter_Callback callback, void *p);
280
281 #else
282
283 #define __USE_GNU
284 #include <link.h>
285 #undef __USE_GNU
286
287 #define elf_w(x) elf64_ ## x
288 #define Elf_W(x) ElfW(x)
289
290 typedef int (*DL_Iter_Callback)(struct dl_phdr_info *info, size_t size, void *ptr);
291
292 #endif
293
294 extern int elf_w(get_proc_name) (pid_t pid, unw_word_t ip,
295 char *buf, size_t len,
296 unw_word_t *offp);
297
298 /*XXXXXXXXXXXXXXXXXXXXXXXXX End unwind_dl.h XXXXXXXXXXXXXXXXXXXXXXXXXX*/
299
300 /*XXXXXXXXXXXXXXXXXXXXXXXXX Start dwarf.h XXXXXXXXXXXXXXXXXXXXXXXXXX*/
301
302 struct dwarf_cursor; /* forward-declaration */
303
304 /* This matches the value used by GCC (see
305 gcc/config/i386.h:DWARF_FRAME_REGISTERS), which leaves plenty of
306 room for expansion. */
307 #define DWARF_NUM_PRESERVED_REGS 17
308
309 #ifdef PLAIN_X86
310 #define DWARF_REGNUM_MAP_LENGTH 19
311 #else
312 #define DWARF_REGNUM_MAP_LENGTH 17
313 #endif
314
315 /* Return TRUE if the ADDR_SPACE uses big-endian byte-order. */
316 #define dwarf_is_big_endian(addr_space) 0
317
318 /* Convert a pointer to a dwarf_cursor structure to a pointer to
319 unw_cursor_t. */
320 #define dwarf_to_cursor(c) ((unw_cursor_t *) (c))
321
322 typedef struct dwarf_loc
323 {
324 unw_word_t val;
325 }
326 dwarf_loc_t;
327
328 /* DWARF expression opcodes. */
329
330 typedef enum
331 {
332 DW_OP_addr = 0x03,
333 DW_OP_deref = 0x06,
334 DW_OP_const1u = 0x08,
335 DW_OP_const1s = 0x09,
336 DW_OP_const2u = 0x0a,
337 DW_OP_const2s = 0x0b,
338 DW_OP_const4u = 0x0c,
339 DW_OP_const4s = 0x0d,
340 DW_OP_const8u = 0x0e,
341 DW_OP_const8s = 0x0f,
342 DW_OP_constu = 0x10,
343 DW_OP_consts = 0x11,
344 DW_OP_dup = 0x12,
345 DW_OP_drop = 0x13,
346 DW_OP_over = 0x14,
347 DW_OP_pick = 0x15,
348 DW_OP_swap = 0x16,
349 DW_OP_rot = 0x17,
350 DW_OP_xderef = 0x18,
351 DW_OP_abs = 0x19,
352 DW_OP_and = 0x1a,
353 DW_OP_div = 0x1b,
354 DW_OP_minus = 0x1c,
355 DW_OP_mod = 0x1d,
356 DW_OP_mul = 0x1e,
357 DW_OP_neg = 0x1f,
358 DW_OP_not = 0x20,
359 DW_OP_or = 0x21,
360 DW_OP_plus = 0x22,
361 DW_OP_plus_uconst = 0x23,
362 DW_OP_shl = 0x24,
363 DW_OP_shr = 0x25,
364 DW_OP_shra = 0x26,
365 DW_OP_xor = 0x27,
366 DW_OP_skip = 0x2f,
367 DW_OP_bra = 0x28,
368 DW_OP_eq = 0x29,
369 DW_OP_ge = 0x2a,
370 DW_OP_gt = 0x2b,
371 DW_OP_le = 0x2c,
372 DW_OP_lt = 0x2d,
373 DW_OP_ne = 0x2e,
374 DW_OP_lit0 = 0x30,
375 DW_OP_lit1, DW_OP_lit2, DW_OP_lit3, DW_OP_lit4, DW_OP_lit5,
376 DW_OP_lit6, DW_OP_lit7, DW_OP_lit8, DW_OP_lit9, DW_OP_lit10,
377 DW_OP_lit11, DW_OP_lit12, DW_OP_lit13, DW_OP_lit14, DW_OP_lit15,
378 DW_OP_lit16, DW_OP_lit17, DW_OP_lit18, DW_OP_lit19, DW_OP_lit20,
379 DW_OP_lit21, DW_OP_lit22, DW_OP_lit23, DW_OP_lit24, DW_OP_lit25,
380 DW_OP_lit26, DW_OP_lit27, DW_OP_lit28, DW_OP_lit29, DW_OP_lit30,
381 DW_OP_lit31,
382 DW_OP_reg0 = 0x50,
383 DW_OP_reg1, DW_OP_reg2, DW_OP_reg3, DW_OP_reg4, DW_OP_reg5,
384 DW_OP_reg6, DW_OP_reg7, DW_OP_reg8, DW_OP_reg9, DW_OP_reg10,
385 DW_OP_reg11, DW_OP_reg12, DW_OP_reg13, DW_OP_reg14, DW_OP_reg15,
386 DW_OP_reg16, DW_OP_reg17, DW_OP_reg18, DW_OP_reg19, DW_OP_reg20,
387 DW_OP_reg21, DW_OP_reg22, DW_OP_reg23, DW_OP_reg24, DW_OP_reg25,
388 DW_OP_reg26, DW_OP_reg27, DW_OP_reg28, DW_OP_reg29, DW_OP_reg30,
389 DW_OP_reg31,
390 DW_OP_breg0 = 0x70,
391 DW_OP_breg1, DW_OP_breg2, DW_OP_breg3, DW_OP_breg4, DW_OP_breg5,
392 DW_OP_breg6, DW_OP_breg7, DW_OP_breg8, DW_OP_breg9, DW_OP_breg10,
393 DW_OP_breg11, DW_OP_breg12, DW_OP_breg13, DW_OP_breg14, DW_OP_breg15,
394 DW_OP_breg16, DW_OP_breg17, DW_OP_breg18, DW_OP_breg19, DW_OP_breg20,
395 DW_OP_breg21, DW_OP_breg22, DW_OP_breg23, DW_OP_breg24, DW_OP_breg25,
396 DW_OP_breg26, DW_OP_breg27, DW_OP_breg28, DW_OP_breg29, DW_OP_breg30,
397 DW_OP_breg31,
398 DW_OP_regx = 0x90,
399 DW_OP_fbreg = 0x91,
400 DW_OP_bregx = 0x92,
401 DW_OP_piece = 0x93,
402 DW_OP_deref_size = 0x94,
403 DW_OP_xderef_size = 0x95,
404 DW_OP_nop = 0x96,
405 DW_OP_push_object_address = 0x97,
406 DW_OP_call2 = 0x98,
407 DW_OP_call4 = 0x99,
408 DW_OP_call_ref = 0x9a,
409 DW_OP_lo_user = 0xe0,
410 DW_OP_hi_user = 0xff
411 }
412 dwarf_expr_op_t;
413
414 #define DWARF_CIE_VERSION 3 /* GCC emits version 1??? */
415
416 #define DWARF_CFA_OPCODE_MASK 0xc0
417 #define DWARF_CFA_OPERAND_MASK 0x3f
418
419 typedef enum
420 {
421 DW_CFA_advance_loc = 0x40,
422 DW_CFA_offset = 0x80,
423 DW_CFA_restore = 0xc0,
424 DW_CFA_nop = 0x00,
425 DW_CFA_set_loc = 0x01,
426 DW_CFA_advance_loc1 = 0x02,
427 DW_CFA_advance_loc2 = 0x03,
428 DW_CFA_advance_loc4 = 0x04,
429 DW_CFA_offset_extended = 0x05,
430 DW_CFA_restore_extended = 0x06,
431 DW_CFA_undefined = 0x07,
432 DW_CFA_same_value = 0x08,
433 DW_CFA_register = 0x09,
434 DW_CFA_remember_state = 0x0a,
435 DW_CFA_restore_state = 0x0b,
436 DW_CFA_def_cfa = 0x0c,
437 DW_CFA_def_cfa_register = 0x0d,
438 DW_CFA_def_cfa_offset = 0x0e,
439 DW_CFA_def_cfa_expression = 0x0f,
440 DW_CFA_expression = 0x10,
441 DW_CFA_offset_extended_sf = 0x11,
442 DW_CFA_def_cfa_sf = 0x12,
443 DW_CFA_def_cfa_offset_sf = 0x13,
444 DW_CFA_lo_user = 0x1c,
445 DW_CFA_MIPS_advance_loc8 = 0x1d,
446 DW_CFA_GNU_window_save = 0x2d,
447 DW_CFA_GNU_args_size = 0x2e,
448 DW_CFA_GNU_negative_offset_extended = 0x2f,
449 DW_CFA_hi_user = 0x3c
450 }
451 dwarf_cfa_t;
452
453 /* DWARF Pointer-Encoding (PEs).
454
455 Pointer-Encodings were invented for the GCC exception-handling
456 support for C++, but they represent a rather generic way of
457 describing the format in which an address/pointer is stored and
458 hence we include the definitions here, in the main dwarf.h file.
459 The Pointer-Encoding format is partially documented in Linux Base
460 Spec v1.3 (http://www.linuxbase.org/spec/). The rest is reverse
461 engineered from GCC.
462
463 */
464 #define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
465 #define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */
466 /* Flag bit. If set, the resulting pointer is the address of the word
467 that contains the final address. */
468 #define DW_EH_PE_indirect 0x80
469
470 /* Pointer-encoding formats: */
471 #define DW_EH_PE_omit 0xff
472 #define DW_EH_PE_ptr 0x00 /* pointer-sized unsigned value */
473 #define DW_EH_PE_uleb128 0x01 /* unsigned LE base-128 value */
474 #define DW_EH_PE_udata2 0x02 /* unsigned 16-bit value */
475 #define DW_EH_PE_udata4 0x03 /* unsigned 32-bit value */
476 #define DW_EH_PE_udata8 0x04 /* unsigned 64-bit value */
477 #define DW_EH_PE_sleb128 0x09 /* signed LE base-128 value */
478 #define DW_EH_PE_sdata2 0x0a /* signed 16-bit value */
479 #define DW_EH_PE_sdata4 0x0b /* signed 32-bit value */
480 #define DW_EH_PE_sdata8 0x0c /* signed 64-bit value */
481
482 /* Pointer-encoding application: */
483 #define DW_EH_PE_absptr 0x00 /* absolute value */
484 #define DW_EH_PE_pcrel 0x10 /* rel. to addr. of encoded value */
485 #define DW_EH_PE_textrel 0x20 /* text-relative (GCC-specific???) */
486 #define DW_EH_PE_datarel 0x30 /* data-relative */
487 /* The following are not documented by LSB v1.3, yet they are used by
488 GCC, presumably they aren't documented by LSB since they aren't
489 used on Linux: */
490 #define DW_EH_PE_funcrel 0x40 /* start-of-procedure-relative */
491 #define DW_EH_PE_aligned 0x50 /* aligned pointer */
492
493 typedef enum
494 {
495 DWARF_WHERE_UNDEF, /* register isn't saved at all */
496 DWARF_WHERE_SAME, /* register has same value as in prev. frame */
497 DWARF_WHERE_CFAREL, /* register saved at CFA-relative address */
498 DWARF_WHERE_REG, /* register saved in another register */
499 DWARF_WHERE_EXPR, /* register saved */
500 }
501 dwarf_where_t;
502
503 typedef struct
504 {
505 dwarf_where_t where; /* how is the register saved? */
506 unw_word_t val; /* where it's saved */
507 }
508 dwarf_save_loc_t;
509
510 /* For uniformity, we'd like to treat the CFA save-location like any
511 other register save-location, but this doesn't quite work, because
512 the CFA can be expressed as a (REGISTER,OFFSET) pair. To handle
513 this, we use two dwarf_save_loc structures to describe the CFA.
514 The first one (CFA_REG_COLUMN), tells us where the CFA is saved.
515 In the case of DWARF_WHERE_EXPR, the CFA is defined by a DWARF
516 location expression whose address is given by member "val". In the
517 case of DWARF_WHERE_REG, member "val" gives the number of the
518 base-register and the "val" member of DWARF_CFA_OFF_COLUMN gives
519 the offset value. */
520 #define DWARF_CFA_REG_COLUMN DWARF_NUM_PRESERVED_REGS
521 #define DWARF_CFA_OFF_COLUMN (DWARF_NUM_PRESERVED_REGS + 1)
522
523 typedef struct dwarf_reg_state
524 {
525 struct dwarf_reg_state *next; /* for rs_stack */
526 dwarf_save_loc_t reg[DWARF_NUM_PRESERVED_REGS + 2];
527 unw_word_t ip; /* ip this rs is for */
528 unw_word_t ret_addr_column; /* indicates which column in the rule table represents return address */
529 unsigned short lru_chain; /* used for least-recently-used chain */
530 unsigned short coll_chain; /* used for hash collisions */
531 unsigned short hint; /* hint for next rs to try (or -1) */
532 char valid, signal_frame;
533 }
534 dwarf_reg_state_t;
535
536 typedef struct dwarf_cie_info
537 {
538 unw_word_t cie_instr_start; /* start addr. of CIE "initial_instructions" */
539 unw_word_t cie_instr_end; /* end addr. of CIE "initial_instructions" */
540 unw_word_t fde_instr_start; /* start addr. of FDE "instructions" */
541 unw_word_t fde_instr_end; /* end addr. of FDE "instructions" */
542 unw_word_t code_align; /* code-alignment factor */
543 unw_word_t data_align; /* data-alignment factor */
544 unw_word_t ret_addr_column; /* column of return-address register */
545 unw_word_t handler; /* address of personality-routine */
546 uint16_t abi;
547 uint16_t tag;
548 uint8_t fde_encoding;
549 uint8_t lsda_encoding;
550 unsigned int sized_augmentation : 1;
551 unsigned int have_abi_marker : 1;
552 unsigned int signal_frame : 1;
553 }
554 dwarf_cie_info_t;
555
556 typedef struct dwarf_state_record
557 {
558 unsigned char fde_encoding;
559 unw_word_t args_size;
560
561 dwarf_reg_state_t rs_initial; /* reg-state after CIE instructions */
562 dwarf_reg_state_t rs_current; /* current reg-state */
563 }
564 dwarf_state_record_t;
565
566 typedef struct dwarf_cursor
567 {
568 void *as_arg; /* argument to address-space callbacks */
569 unw_addr_space_t as; /* reference to per-address-space info */
570
571 unw_word_t cfa; /* canonical frame address; aka frame-/stack-pointer */
572 unw_word_t ip; /* instruction pointer */
573 unw_word_t args_size; /* size of arguments */
574 unw_word_t ret_addr_column; /* column for return-address */
575 unw_word_t eh_args[UNW_TDEP_NUM_EH_REGS];
576 unsigned int eh_valid_mask;
577
578 dwarf_loc_t loc[DWARF_NUM_PRESERVED_REGS];
579
580 unsigned int pi_valid :1; /* is proc_info valid? */
581 unw_proc_info_t pi; /* info about current procedure */
582
583 short hint; /* faster lookup of the rs cache */
584 short prev_rs;
585
586 int use_prev_instr;
587 }
588 dwarf_cursor_t;
589
590 #define DWARF_LOG_UNW_CACHE_SIZE 7
591 #define DWARF_UNW_CACHE_SIZE (1 << DWARF_LOG_UNW_CACHE_SIZE)
592
593 #define DWARF_LOG_UNW_HASH_SIZE (DWARF_LOG_UNW_CACHE_SIZE + 1)
594 #define DWARF_UNW_HASH_SIZE (1 << DWARF_LOG_UNW_HASH_SIZE)
595
596 typedef unsigned char unw_hash_index_t;
597
598 struct dwarf_rs_cache
599 {
600 unsigned short lru_head; /* index of lead-recently used rs */
601 unsigned short lru_tail; /* index of most-recently used rs */
602
603 /* hash table that maps instruction pointer to rs index: */
604 unsigned short hash[DWARF_UNW_HASH_SIZE];
605
606 uint32_t generation; /* generation number */
607
608 /* rs cache: */
609 dwarf_reg_state_t buckets[DWARF_UNW_CACHE_SIZE];
610 };
611
612 /* Convenience macros: */
613 #define dwarf_init UNW_ARCH_OBJ (dwarf_init)
614 #define dwarf_find_proc_info UNW_OBJ (dwarf_find_proc_info)
615 #define dwarf_search_unwind_table UNW_OBJ (dwarf_search_unwind_table)
616 #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
617 #define dwarf_put_unwind_info UNW_OBJ (dwarf_put_unwind_info)
618 #define dwarf_eval_expr UNW_OBJ (dwarf_eval_expr)
619 #define dwarf_extract_proc_info_from_fde \
620 UNW_OBJ (dwarf_extract_proc_info_from_fde)
621 #define dwarf_find_save_locs UNW_OBJ (dwarf_find_save_locs)
622 #define dwarf_create_state_record UNW_OBJ (dwarf_create_state_record)
623 #define dwarf_make_proc_info UNW_OBJ (dwarf_make_proc_info)
624 #define dwarf_read_encoded_pointer UNW_OBJ (dwarf_read_encoded_pointer)
625 #define dwarf_step UNW_OBJ (dwarf_step)
626
627 HIDDEN int dwarf_find_proc_info (unw_addr_space_t as, unw_word_t ip,
628 unw_proc_info_t *pi,
629 int need_unwind_info, void *arg);
630 HIDDEN int dwarf_search_unwind_table (unw_addr_space_t as,
631 unw_word_t ip,
632 unw_dyn_info_t *di,
633 unw_proc_info_t *pi,
634 int need_unwind_info, void *arg);
635 HIDDEN int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr,
636 unw_word_t len, unw_word_t *valp,
637 int *is_register);
638 HIDDEN int dwarf_extract_proc_info_from_fde (unw_addr_space_t as,
639 unw_accessors_t *a,
640 unw_word_t *fde_addr,
641 unw_proc_info_t *pi,
642 int need_unwind_info,
643 unw_word_t base,
644 void *arg);
645 HIDDEN int dwarf_find_save_locs (struct dwarf_cursor *c);
646 HIDDEN int dwarf_read_encoded_pointer (unw_addr_space_t as,
647 unw_accessors_t *a,
648 unw_word_t *addr,
649 unsigned char encoding,
650 const unw_proc_info_t *pi,
651 unw_word_t *valp, void *arg);
652 HIDDEN int dwarf_step (struct dwarf_cursor *c);
653
654 /*XXXXXXXXXXXXXXXXXXXXXXXXX End dwarf.h XXXXXXXXXXXXXXXXXXXXXXXXXX*/
655
656 #ifdef CONFIG_DEBUG_FRAME
657 struct unw_debug_frame_list
658 {
659 /* The start (inclusive) and end (exclusive) of the described region. */
660 unw_word_t start;
661 unw_word_t end;
662 /* The debug frame itself. */
663 char *debug_frame;
664 size_t debug_frame_size;
665 /* Index (for binary search). */
666 struct table_entry *index;
667 size_t index_size;
668 /* Pointer to next descriptor. */
669 struct unw_debug_frame_list *next;
670 };
671 #endif
672
673 struct unw_addr_space
674 {
675 void *mem_pool;
676 struct unw_accessors acc;
677 unw_caching_policy_t caching_policy;
678 #ifdef HAVE_ATOMIC_OPS_H
679 AO_t cache_generation;
680 #else
681 uint32_t cache_generation;
682 #endif
683 struct dwarf_rs_cache global_cache;
684 #ifdef CONFIG_DEBUG_FRAME
685 struct unw_debug_frame_list *debug_frames;
686 #endif
687 unw_word_t safe_start_address, safe_end_address;
688 long num_safe_addresses;
689 unw_word_t *safe_start_addresses, *safe_end_addresses;
690 int saw_bad_ptr;
691 };
692
693 struct cursor
694 {
695 struct dwarf_cursor dwarf; /* must be first */
696
697 /* Format of sigcontext structure and address at which it is
698 stored: */
699 enum
700 {
701 X86_SCF_NONE, /* no signal frame encountered */
702 X86_SCF_LINUX_SIGFRAME, /* classic x86 sigcontext */
703 X86_SCF_LINUX_RT_SIGFRAME, /* POSIX ucontext_t */
704 ARM_SCF_NONE
705 }
706 sigcontext_format;
707 unw_word_t sigcontext_addr;
708 };
709
710 #define DWARF_GET_LOC(l) ((l).val)
711
712 # define DWARF_NULL_LOC DWARF_LOC (0, 0)
713 # define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0)
714 # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) })
715 # define DWARF_IS_REG_LOC(l) 0
716 # define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \
717 tdep_uc_addr((c)->as_arg, (r)), 0))
718 # define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0)
719 # define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \
720 tdep_uc_addr((c)->as_arg, (r)), 0))
721
722 static void *safe_pointer(unw_addr_space_t, unw_word_t);
723
724 static inline int
dwarf_getfp(struct dwarf_cursor * c,dwarf_loc_t loc,unw_fpreg_t * val)725 dwarf_getfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t *val)
726 {
727 if (!DWARF_GET_LOC (loc))
728 return -1;
729 *val = *(unw_fpreg_t *) safe_pointer(c->as, DWARF_GET_LOC (loc));
730 return 0;
731 }
732
733 static inline int
dwarf_putfp(struct dwarf_cursor * c,dwarf_loc_t loc,unw_fpreg_t val)734 dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val)
735 {
736 if (!DWARF_GET_LOC (loc))
737 return -1;
738 *(unw_fpreg_t *) safe_pointer(c->as, DWARF_GET_LOC (loc)) = val;
739 return 0;
740 }
741
742 static inline int
dwarf_get(struct dwarf_cursor * c,dwarf_loc_t loc,unw_word_t * val)743 dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val)
744 {
745 if (!DWARF_GET_LOC (loc))
746 return -1;
747 *val = *(unw_word_t *) safe_pointer(c->as, DWARF_GET_LOC (loc));
748 return 0;
749 }
750
751 static inline int
dwarf_put(struct dwarf_cursor * c,dwarf_loc_t loc,unw_word_t val)752 dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val)
753 {
754 if (!DWARF_GET_LOC (loc))
755 return -1;
756 *(unw_word_t *) safe_pointer(c->as, DWARF_GET_LOC (loc)) = val;
757 return 0;
758 }
759
760 #define tdep_needs_initialization UNW_OBJ(needs_initialization)
761 #define tdep_init UNW_OBJ(init)
762 /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
763 tdep_search_unwind_table. */
764 #define tdep_search_unwind_table dwarf_search_unwind_table
765 #define tdep_uc_addr UNW_ARCH_OBJ(uc_addr)
766 #define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image)
767 #define tdep_access_reg UNW_OBJ(access_reg)
768 #define tdep_access_fpreg UNW_OBJ(access_fpreg)
769
770 # define tdep_find_proc_info(c,ip,n) \
771 dwarf_find_proc_info((c)->as, (ip), &(c)->pi, (n), \
772 (c)->as_arg)
773 # define tdep_put_unwind_info(as,pi,arg) \
774 dwarf_put_unwind_info((as), (pi), (arg))
775
776 #define tdep_get_as(c) ((c)->dwarf.as)
777 #define tdep_get_as_arg(c) ((c)->dwarf.as_arg)
778 #define tdep_get_ip(c) ((c)->dwarf.ip)
779 #define tdep_get_cfa(c) ((c)->dwarf.cfa)
780 #define tdep_big_endian(as) 0
781
782 extern int tdep_needs_initialization;
783
784 extern void tdep_init (void);
785 extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
786 unw_dyn_info_t *di, unw_proc_info_t *pi,
787 int need_unwind_info, void *arg);
788 extern void *tdep_uc_addr (unw_context_t *uc, int reg);
789 extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip,
790 unsigned long *segbase, unsigned long *mapoff);
791 extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
792 unw_word_t *valp, int write);
793 extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
794 unw_fpreg_t *valp, int write);
795
796
797 /*XXXXXXXXXXXXXXXXXXXXXXXXX Start dwarf_i.h XXXXXXXXXXXXXXXXXXXXXXXXXX*/
798
799 #define dwarf_to_unw_regnum_map UNW_OBJ (dwarf_to_unw_regnum_map)
800
801 HIDDEN int dwarf_to_unw_regnum(int reg);
802
803 /* In the local-only case, we can let the compiler directly access
804 memory and don't need to worry about differing byte-order. */
805
806 typedef union
807 {
808 int8_t s8;
809 int16_t s16;
810 int32_t s32;
811 int64_t s64;
812 uint8_t u8;
813 uint16_t u16;
814 uint32_t u32;
815 uint64_t u64;
816 unw_word_t w;
817 void *ptr;
818 }
819 dwarf_misaligned_value_t;
820
821 static inline int
dwarf_reads8(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,int8_t * val,void * arg)822 dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
823 int8_t *val, void *arg)
824 {
825 dwarf_misaligned_value_t *mvp = (void *)safe_pointer(as, *addr);
826
827 *val = mvp->s8;
828 *addr += sizeof (mvp->s8);
829 return 0;
830 }
831
832 static inline int
dwarf_reads16(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,int16_t * val,void * arg)833 dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
834 int16_t *val, void *arg)
835 {
836 dwarf_misaligned_value_t *mvp = (void *)safe_pointer(as, *addr);
837
838 *val = mvp->s16;
839 *addr += sizeof (mvp->s16);
840 return 0;
841 }
842
843 static inline int
dwarf_reads32(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,int32_t * val,void * arg)844 dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
845 int32_t *val, void *arg)
846 {
847 dwarf_misaligned_value_t *mvp = (void *)safe_pointer(as, *addr);
848
849 *val = mvp->s32;
850 *addr += sizeof (mvp->s32);
851 return 0;
852 }
853
854 static inline int
dwarf_reads64(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,int64_t * val,void * arg)855 dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
856 int64_t *val, void *arg)
857 {
858 dwarf_misaligned_value_t *mvp = (void *)safe_pointer(as, *addr);
859
860 *val = mvp->s64;
861 *addr += sizeof (mvp->s64);
862 return 0;
863 }
864
865 static inline int
dwarf_readu8(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,uint8_t * val,void * arg)866 dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
867 uint8_t *val, void *arg)
868 {
869 dwarf_misaligned_value_t *mvp = (void *)safe_pointer(as, *addr);
870
871 *val = mvp->u8;
872 *addr += sizeof (mvp->u8);
873 return 0;
874 }
875
876 static inline int
dwarf_readu16(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,uint16_t * val,void * arg)877 dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
878 uint16_t *val, void *arg)
879 {
880 dwarf_misaligned_value_t *mvp = (void *)safe_pointer(as, *addr);
881
882 *val = mvp->u16;
883 *addr += sizeof (mvp->u16);
884 return 0;
885 }
886
887 static inline int
dwarf_readu32(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,uint32_t * val,void * arg)888 dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
889 uint32_t *val, void *arg)
890 {
891 dwarf_misaligned_value_t *mvp = (void *)safe_pointer(as, *addr);
892
893 *val = mvp->u32;
894 *addr += sizeof (mvp->u32);
895 return 0;
896 }
897
898 static inline int
dwarf_readu64(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,uint64_t * val,void * arg)899 dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
900 uint64_t *val, void *arg)
901 {
902 dwarf_misaligned_value_t *mvp = (void *)safe_pointer(as, *addr);
903
904 *val = mvp->u64;
905 *addr += sizeof (mvp->u64);
906 return 0;
907 }
908
909 static inline int
dwarf_readw(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,unw_word_t * val,void * arg)910 dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
911 unw_word_t *val, void *arg)
912 {
913 dwarf_misaligned_value_t *mvp = (void *)safe_pointer(as, *addr);
914
915 *val = mvp->w;
916 *addr += sizeof (mvp->w);
917 return 0;
918 }
919
920 /* Read an unsigned "little-endian base 128" value. See Chapter 7.6
921 of DWARF spec v3. */
922
923 static inline int
dwarf_read_uleb128(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,unw_word_t * valp,void * arg)924 dwarf_read_uleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
925 unw_word_t *valp, void *arg)
926 {
927 unw_word_t val = 0, shift = 0;
928 unsigned char byte;
929 int ret;
930
931 do
932 {
933 if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
934 return ret;
935
936 val |= ((unw_word_t) byte & 0x7f) << shift;
937 shift += 7;
938 }
939 while (byte & 0x80);
940
941 *valp = val;
942 return 0;
943 }
944
945 /* Read a signed "little-endian base 128" value. See Chapter 7.6 of
946 DWARF spec v3. */
947
948 static inline int
dwarf_read_sleb128(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,unw_word_t * valp,void * arg)949 dwarf_read_sleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
950 unw_word_t *valp, void *arg)
951 {
952 unw_word_t val = 0, shift = 0;
953 unsigned char byte;
954 int ret;
955
956 do
957 {
958 if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
959 return ret;
960
961 val |= ((unw_word_t) byte & 0x7f) << shift;
962 shift += 7;
963 }
964 while (byte & 0x80);
965
966 if (shift < 8 * sizeof (unw_word_t) && (byte & 0x40) != 0)
967 /* sign-extend negative value */
968 val |= ((unw_word_t) -1) << shift;
969
970 *valp = val;
971 return 0;
972 }
973
974 static ALWAYS_INLINE int
dwarf_read_encoded_pointer_inlined(unw_addr_space_t as,unw_accessors_t * a,unw_word_t * addr,unsigned char encoding,const unw_proc_info_t * pi,unw_word_t * valp,void * arg)975 dwarf_read_encoded_pointer_inlined (unw_addr_space_t as, unw_accessors_t *a,
976 unw_word_t *addr, unsigned char encoding,
977 const unw_proc_info_t *pi,
978 unw_word_t *valp, void *arg)
979 {
980 unw_word_t val, initial_addr = *addr;
981 uint16_t uval16;
982 uint32_t uval32;
983 uint64_t uval64;
984 int16_t sval16;
985 int32_t sval32;
986 int64_t sval64;
987 int ret;
988
989 /* DW_EH_PE_omit and DW_EH_PE_aligned don't follow the normal
990 format/application encoding. Handle them first. */
991 if (encoding == DW_EH_PE_omit)
992 {
993 *valp = 0;
994 return 0;
995 }
996 else if (encoding == DW_EH_PE_aligned)
997 {
998 *addr = (initial_addr + sizeof (unw_word_t) - 1) & -sizeof (unw_word_t);
999 return dwarf_readw (as, a, addr, valp, arg);
1000 }
1001
1002 switch (encoding & DW_EH_PE_FORMAT_MASK)
1003 {
1004 case DW_EH_PE_ptr:
1005 if ((ret = dwarf_readw (as, a, addr, &val, arg)) < 0)
1006 return ret;
1007 break;
1008
1009 case DW_EH_PE_uleb128:
1010 if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
1011 return ret;
1012 break;
1013
1014 case DW_EH_PE_udata2:
1015 if ((ret = dwarf_readu16 (as, a, addr, &uval16, arg)) < 0)
1016 return ret;
1017 val = uval16;
1018 break;
1019
1020 case DW_EH_PE_udata4:
1021 if ((ret = dwarf_readu32 (as, a, addr, &uval32, arg)) < 0)
1022 return ret;
1023 val = uval32;
1024 break;
1025
1026 case DW_EH_PE_udata8:
1027 if ((ret = dwarf_readu64 (as, a, addr, &uval64, arg)) < 0)
1028 return ret;
1029 val = uval64;
1030 break;
1031
1032 case DW_EH_PE_sleb128:
1033 if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
1034 return ret;
1035 break;
1036
1037 case DW_EH_PE_sdata2:
1038 if ((ret = dwarf_reads16 (as, a, addr, &sval16, arg)) < 0)
1039 return ret;
1040 val = sval16;
1041 break;
1042
1043 case DW_EH_PE_sdata4:
1044 if ((ret = dwarf_reads32 (as, a, addr, &sval32, arg)) < 0)
1045 return ret;
1046 val = sval32;
1047 break;
1048
1049 case DW_EH_PE_sdata8:
1050 if ((ret = dwarf_reads64 (as, a, addr, &sval64, arg)) < 0)
1051 return ret;
1052 val = sval64;
1053 break;
1054
1055 default:
1056 Debug (1, "unexpected encoding format 0x%x\n",
1057 encoding & DW_EH_PE_FORMAT_MASK);
1058 return -UNW_EINVAL;
1059 }
1060
1061 if (val == 0)
1062 {
1063 /* 0 is a special value and always absolute. */
1064 *valp = 0;
1065 return 0;
1066 }
1067
1068 switch (encoding & DW_EH_PE_APPL_MASK)
1069 {
1070 case DW_EH_PE_absptr:
1071 break;
1072
1073 case DW_EH_PE_pcrel:
1074 val += initial_addr;
1075 break;
1076
1077 case DW_EH_PE_datarel:
1078 /* XXX For now, assume that data-relative addresses are relative
1079 to the global pointer. */
1080 val += pi->gp;
1081 break;
1082
1083 case DW_EH_PE_funcrel:
1084 val += pi->start_ip;
1085 break;
1086
1087 case DW_EH_PE_textrel:
1088 /* XXX For now we don't support text-rel values. If there is a
1089 platform which needs this, we probably would have to add a
1090 "segbase" member to unw_proc_info_t. */
1091 default:
1092 Debug (1, "unexpected application type 0x%x\n",
1093 encoding & DW_EH_PE_APPL_MASK);
1094 return -UNW_EINVAL;
1095 }
1096
1097 if (encoding & DW_EH_PE_indirect)
1098 {
1099 unw_word_t indirect_addr = val;
1100
1101 if ((ret = dwarf_readw (as, a, &indirect_addr, &val, arg)) < 0)
1102 return ret;
1103 }
1104
1105 *valp = val;
1106 return 0;
1107 }
1108
1109 /*XXXXXXXXXXXXXXXXXXXXXXXXX End dwarf_i.h XXXXXXXXXXXXXXXXXXXXXXXXXX*/
1110
1111 /*XXXXXXXXXXXXXXXXXXXXXXXXX Start dwarf-eh.h XXXXXXXXXXXXXXXXXXXXXXXXXX*/
1112
1113 /* This header file defines the format of a DWARF exception-header
1114 section (.eh_frame_hdr, pointed to by program-header
1115 PT_GNU_EH_FRAME). The exception-header is self-describing in the
1116 sense that the format of the addresses contained in it is expressed
1117 as a one-byte type-descriptor called a "pointer-encoding" (PE).
1118
1119 The exception header encodes the address of the .eh_frame section
1120 and optionally contains a binary search table for the
1121 Frame Descriptor Entries (FDEs) in the .eh_frame. The contents of
1122 .eh_frame has the format described by the DWARF v3 standard
1123 (http://www.eagercon.com/dwarf/dwarf3std.htm), except that code
1124 addresses may be encoded in different ways. Also, .eh_frame has
1125 augmentations that allow encoding a language-specific data-area
1126 (LSDA) pointer and a pointer to a personality-routine.
1127
1128 Details:
1129
1130 The Common Information Entry (CIE) associated with an FDE may
1131 contain an augmentation string. Each character in this string has
1132 a specific meaning and either one or two associated operands. The
1133 operands are stored in an augmentation body which appears right
1134 after the "return_address_register" member and before the
1135 "initial_instructions" member. The operands appear in the order
1136 in which the characters appear in the string. For example, if the
1137 augmentation string is "zL", the operand for 'z' would be first in
1138 the augmentation body and the operand for 'L' would be second.
1139 The following characters are supported for the CIE augmentation
1140 string:
1141
1142 'z': The operand for this character is a uleb128 value that gives the
1143 length of the CIE augmentation body, not counting the length
1144 of the uleb128 operand itself. If present, this code must
1145 appear as the first character in the augmentation body.
1146
1147 'L': Indicates that the FDE's augmentation body contains an LSDA
1148 pointer. The operand for this character is a single byte
1149 that specifies the pointer-encoding (PE) that is used for
1150 the LSDA pointer.
1151
1152 'R': Indicates that the code-pointers (FDE members
1153 "initial_location" and "address_range" and the operand for
1154 DW_CFA_set_loc) in the FDE have a non-default encoding. The
1155 operand for this character is a single byte that specifies
1156 the pointer-encoding (PE) that is used for the
1157 code-pointers. Note: the "address_range" member is always
1158 encoded as an absolute value. Apart from that, the specified
1159 FDE pointer-encoding applies.
1160
1161 'P': Indicates the presence of a personality routine (handler).
1162 The first operand for this character specifies the
1163 pointer-encoding (PE) that is used for the second operand,
1164 which specifies the address of the personality routine.
1165
1166 If the augmentation string contains any other characters, the
1167 remainder of the augmentation string should be ignored.
1168 Furthermore, if the size of the augmentation body is unknown
1169 (i.e., 'z' is not the first character of the augmentation string),
1170 then the entire CIE as well all associated FDEs must be ignored.
1171
1172 A Frame Descriptor Entries (FDE) may contain an augmentation body
1173 which, if present, appears right after the "address_range" member
1174 and before the "instructions" member. The contents of this body
1175 is implicitly defined by the augmentation string of the associated
1176 CIE. The meaning of the characters in the CIE's augmentation
1177 string as far as FDEs are concerned is as follows:
1178
1179 'z': The first operand in the FDE's augmentation body specifies
1180 the total length of the augmentation body as a uleb128 (not
1181 counting the length of the uleb128 operand itself).
1182
1183 'L': The operand for this character is an LSDA pointer, encoded
1184 in the format specified by the corresponding operand in the
1185 CIE's augmentation body.
1186
1187 */
1188
1189 #define DW_EH_VERSION 1 /* The version we're implementing */
1190
1191 struct dwarf_eh_frame_hdr
1192 {
1193 unsigned char version;
1194 unsigned char eh_frame_ptr_enc;
1195 unsigned char fde_count_enc;
1196 unsigned char table_enc;
1197 /* The rest of the header is variable-length and consists of the
1198 following members:
1199
1200 encoded_t eh_frame_ptr;
1201 encoded_t fde_count;
1202 struct
1203 {
1204 encoded_t start_ip; // first address covered by this FDE
1205 encoded_t fde_addr; // address of the FDE
1206 }
1207 binary_search_table[fde_count]; */
1208 };
1209
1210 /*XXXXXXXXXXXXXXXXXXXXXXXXX End dwarf-eh.h XXXXXXXXXXXXXXXXXXXXXXXXXX*/
1211
1212 #endif /* libunwind_i_h */
1213