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