• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 part of libunwind.
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  #ifndef IA64_LIBUNWIND_I_H
27  #define IA64_LIBUNWIND_I_H
28  
29  /* Target-dependent definitions that are internal to libunwind but need
30     to be shared with target-independent code.  */
31  
32  #include "elf64.h"
33  /* ANDROID support update. */
34  #include "map_info.h"
35  /* End of ANDROID update. */
36  #include "mempool.h"
37  
38  typedef struct
39    {
40      /* no ia64-specific fast trace */
41    }
42  unw_tdep_frame_t;
43  
44  enum ia64_pregnum
45    {
46      /* primary unat: */
47      IA64_REG_PRI_UNAT_GR,
48      IA64_REG_PRI_UNAT_MEM,
49  
50      /* memory stack (order matters: see build_script() */
51      IA64_REG_PSP,			/* previous memory stack pointer */
52      /* register stack */
53      IA64_REG_BSP,			/* register stack pointer */
54      IA64_REG_BSPSTORE,
55      IA64_REG_PFS,			/* previous function state */
56      IA64_REG_RNAT,
57      /* instruction pointer: */
58      IA64_REG_IP,
59  
60      /* preserved registers: */
61      IA64_REG_R4, IA64_REG_R5, IA64_REG_R6, IA64_REG_R7,
62      IA64_REG_NAT4, IA64_REG_NAT5, IA64_REG_NAT6, IA64_REG_NAT7,
63      IA64_REG_UNAT, IA64_REG_PR, IA64_REG_LC, IA64_REG_FPSR,
64      IA64_REG_B1, IA64_REG_B2, IA64_REG_B3, IA64_REG_B4, IA64_REG_B5,
65      IA64_REG_F2, IA64_REG_F3, IA64_REG_F4, IA64_REG_F5,
66      IA64_REG_F16, IA64_REG_F17, IA64_REG_F18, IA64_REG_F19,
67      IA64_REG_F20, IA64_REG_F21, IA64_REG_F22, IA64_REG_F23,
68      IA64_REG_F24, IA64_REG_F25, IA64_REG_F26, IA64_REG_F27,
69      IA64_REG_F28, IA64_REG_F29, IA64_REG_F30, IA64_REG_F31,
70      IA64_NUM_PREGS
71    };
72  
73  #ifdef UNW_LOCAL_ONLY
74  
75  typedef unw_word_t ia64_loc_t;
76  
77  #else /* !UNW_LOCAL_ONLY */
78  
79  typedef struct ia64_loc
80    {
81      unw_word_t w0, w1;
82    }
83  ia64_loc_t;
84  
85  #endif /* !UNW_LOCAL_ONLY */
86  
87  #include "script.h"
88  
89  #define ABI_UNKNOWN			0
90  #define ABI_LINUX			1
91  #define ABI_HPUX			2
92  #define ABI_FREEBSD			3
93  #define ABI_OPENVMS			4
94  #define ABI_NSK				5	/* Tandem/HP Non-Stop Kernel */
95  #define ABI_WINDOWS			6
96  
97  struct unw_addr_space
98    {
99      struct unw_accessors acc;
100      int big_endian;
101      int abi;	/* abi < 0 => unknown, 0 => SysV, 1 => HP-UX, 2 => Windows */
102      unw_caching_policy_t caching_policy;
103  #ifdef HAVE_ATOMIC_OPS_H
104      AO_t cache_generation;
105  #else
106      uint32_t cache_generation;
107  #endif
108      unw_word_t dyn_generation;
109      unw_word_t dyn_info_list_addr;	/* (cached) dyn_info_list_addr */
110  #ifndef UNW_REMOTE_ONLY
111      unsigned long long shared_object_removals;
112  #endif
113  
114      struct ia64_script_cache global_cache;
115  
116      /* ANDROID support update. */
117      struct map_info *map_list;
118      /* End of ANDROID update. */
119     };
120  
121  /* Note: The ABI numbers in the ABI-markers (.unwabi directive) are
122     not the same as the above ABI numbers.  */
123  #define ABI_MARKER_OLD_LINUX_SIGTRAMP	((0 << 8) | 's')
124  #define ABI_MARKER_OLD_LINUX_INTERRUPT	((0 << 8) | 'i')
125  #define ABI_MARKER_HP_UX_SIGTRAMP	((1 << 8) | 1)
126  #define ABI_MARKER_LINUX_SIGTRAMP	((3 << 8) | 's')
127  #define ABI_MARKER_LINUX_INTERRUPT	((3 << 8) | 'i')
128  
129  struct cursor
130    {
131      void *as_arg;		/* argument to address-space callbacks */
132      unw_addr_space_t as;	/* reference to per-address-space info */
133  
134      /* IP, CFM, and predicate cache (these are always equal to the
135         values stored in ip_loc, cfm_loc, and pr_loc,
136         respectively).  */
137      unw_word_t ip;		/* instruction pointer value */
138      unw_word_t cfm;		/* current frame mask */
139      unw_word_t pr;		/* current predicate values */
140  
141      /* current frame info: */
142      unw_word_t bsp;		/* backing store pointer value */
143      unw_word_t sp;		/* stack pointer value */
144      unw_word_t psp;		/* previous sp value */
145      ia64_loc_t cfm_loc;		/* cfm save location (or NULL) */
146      ia64_loc_t ec_loc;		/* ar.ec save location (usually cfm_loc) */
147      ia64_loc_t loc[IA64_NUM_PREGS];
148  
149      unw_word_t eh_args[4];	/* exception handler arguments */
150      unw_word_t sigcontext_addr;	/* address of sigcontext or 0 */
151      unw_word_t sigcontext_off;	/* sigcontext-offset relative to signal sp */
152  
153      short hint;
154      short prev_script;
155  
156      uint8_t nat_bitnr[4];	/* NaT bit numbers for r4-r7 */
157      uint16_t abi_marker;	/* abi_marker for current frame (if any) */
158      uint16_t last_abi_marker;	/* last abi_marker encountered so far */
159      uint8_t eh_valid_mask;
160  
161      unsigned int pi_valid :1;		/* is proc_info valid? */
162      unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */
163      unw_proc_info_t pi;		/* info about current procedure */
164  
165      /* In case of stack-discontiguities, such as those introduced by
166         signal-delivery on an alternate signal-stack (see
167         sigaltstack(2)), we use the following data-structure to keep
168         track of the register-backing-store areas across on which the
169         current frame may be backed up.  Since there are at most 96
170         stacked registers and since we only have to track the current
171         frame and only areas that are not empty, this puts an upper
172         limit on the # of backing-store areas we have to track.
173  
174         Note that the rbs-area indexed by rbs_curr identifies the
175         rbs-area that was in effect at the time AR.BSP had the value
176         c->bsp.  However, this rbs area may not actually contain the
177         value in the register that c->bsp corresponds to because that
178         register may not have gotten spilled until much later, when a
179         possibly different rbs-area might have been in effect
180         already.  */
181      uint8_t rbs_curr;		/* index of curr. rbs-area (contains c->bsp) */
182      uint8_t rbs_left_edge;	/* index of inner-most valid rbs-area */
183      struct rbs_area
184        {
185  	unw_word_t end;
186  	unw_word_t size;
187  	ia64_loc_t rnat_loc;
188        }
189      rbs_area[96 + 2];	/* 96 stacked regs + 1 extra stack on each side... */
190  };
191  
192  struct ia64_global_unwind_state
193    {
194      pthread_mutex_t lock;		/* global data lock */
195  
196      volatile char init_done;
197  
198      /* Table of registers that prologues can save (and order in which
199         they're saved).  */
200      const unsigned char save_order[8];
201  
202      /*
203       * uc_addr() may return pointers to these variables.  We need to
204       * make sure they don't get written via ia64_put() or
205       * ia64_putfp().  To make it possible to test for these variables
206       * quickly, we collect them in a single sub-structure.
207       */
208      struct
209        {
210  	unw_word_t  r0;			/* r0 is byte-order neutral */
211  	unw_fpreg_t f0;			/* f0 is byte-order neutral */
212  	unw_fpreg_t f1_le, f1_be;	/* f1 is byte-order dependent */
213        }
214      read_only;
215      unw_fpreg_t nat_val_le, nat_val_be;
216      unw_fpreg_t int_val_le, int_val_be;
217  
218      struct mempool reg_state_pool;
219      struct mempool labeled_state_pool;
220  
221  # if UNW_DEBUG
222      const char *preg_name[IA64_NUM_PREGS];
223  # endif
224    };
225  
226  #define tdep_getcontext_trace           unw_getcontext
227  #define tdep_init_done			unw.init_done
228  #define tdep_init			UNW_OBJ(init)
229  /* Platforms that support UNW_INFO_FORMAT_TABLE need to define
230     tdep_search_unwind_table.  */
231  #define tdep_search_unwind_table	unw_search_ia64_unwind_table
232  #define tdep_find_unwind_table	ia64_find_unwind_table
233  #define tdep_find_proc_info		UNW_OBJ(find_proc_info)
234  #define tdep_uc_addr			UNW_OBJ(uc_addr)
235  #define tdep_get_elf_image		UNW_ARCH_OBJ(get_elf_image)
236  #define tdep_access_reg			UNW_OBJ(access_reg)
237  #define tdep_access_fpreg		UNW_OBJ(access_fpreg)
238  #define tdep_fetch_frame(c,ip,n)	do {} while(0)
239  #define tdep_cache_frame(c,rs)		do {} while(0)
240  #define tdep_reuse_frame(c,rs)		do {} while(0)
241  #define tdep_stash_frame(c,rs)		do {} while(0)
242  #define tdep_trace(cur,addr,n)		(-UNW_ENOINFO)
243  #define tdep_get_as(c)			((c)->as)
244  #define tdep_get_as_arg(c)		((c)->as_arg)
245  #define tdep_get_ip(c)			((c)->ip)
246  #define tdep_big_endian(as)		((c)->as->big_endian != 0)
247  
248  #ifndef UNW_LOCAL_ONLY
249  # define tdep_put_unwind_info		UNW_OBJ(put_unwind_info)
250  #endif
251  
252  /* This can't be an UNW_ARCH_OBJ() because we need separate
253     unw.initialized flags for the local-only and generic versions of
254     the library.  Also, if we wanted to have a single, shared global
255     data structure, we couldn't declare "unw" as HIDDEN/PROTECTED.  */
256  #define unw				UNW_OBJ(data)
257  
258  extern void tdep_init (void);
259  extern int tdep_find_unwind_table (struct elf_dyn_info *edi,
260  				   unw_addr_space_t as, char *path,
261  				   unw_word_t segbase, unw_word_t mapoff,
262  				   unw_word_t ip);
263  extern int tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip,
264  				unw_proc_info_t *pi, int need_unwind_info,
265  				void *arg);
266  extern void tdep_put_unwind_info (unw_addr_space_t as,
267  				  unw_proc_info_t *pi, void *arg);
268  extern void *tdep_uc_addr (ucontext_t *uc, unw_regnum_t regnum,
269  			   uint8_t *nat_bitnr);
270  /* ANDROID support update. */
271  extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
272  			       pid_t pid, unw_word_t ip,
273  			       unsigned long *segbase, unsigned long *mapoff,
274  			       char **path);
275  /* End of ANDROID update. */
276  extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
277  			    unw_word_t *valp, int write);
278  extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg,
279  			      unw_fpreg_t *valp, int write);
280  
281  extern struct ia64_global_unwind_state unw;
282  
283  /* In user-level, we have no reasonable way of determining the base of
284     an arbitrary backing-store.  We default to half the
285     address-space.  */
286  #define rbs_get_base(c,bspstore,rbs_basep)				\
287  	(*(rbs_basep) = (bspstore) - (((unw_word_t) 1) << 63), 0)
288  
289  #endif /* IA64_LIBUNWIND_I_H */
290