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