libunwind_i.h revision dac2d001afb1fa7040ca7d8ae57032f684d7023e
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 5This file is part of libunwind. 6 7Permission is hereby granted, free of charge, to any person obtaining 8a copy of this software and associated documentation files (the 9"Software"), to deal in the Software without restriction, including 10without limitation the rights to use, copy, modify, merge, publish, 11distribute, sublicense, and/or sell copies of the Software, and to 12permit persons to whom the Software is furnished to do so, subject to 13the following conditions: 14 15The above copyright notice and this permission notice shall be 16included in all copies or substantial portions of the Software. 17 18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 25 26#ifndef 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#include "mempool.h" 34 35enum ia64_pregnum 36 { 37 /* primary unat: */ 38 IA64_REG_PRI_UNAT_GR, 39 IA64_REG_PRI_UNAT_MEM, 40 41 /* memory stack (order matters: see build_script() */ 42 IA64_REG_PSP, /* previous memory stack pointer */ 43 /* register stack */ 44 IA64_REG_BSP, /* register stack pointer */ 45 IA64_REG_BSPSTORE, 46 IA64_REG_PFS, /* previous function state */ 47 IA64_REG_RNAT, 48 /* instruction pointer: */ 49 IA64_REG_IP, 50 51 /* preserved registers: */ 52 IA64_REG_R4, IA64_REG_R5, IA64_REG_R6, IA64_REG_R7, 53 IA64_REG_NAT4, IA64_REG_NAT5, IA64_REG_NAT6, IA64_REG_NAT7, 54 IA64_REG_UNAT, IA64_REG_PR, IA64_REG_LC, IA64_REG_FPSR, 55 IA64_REG_B1, IA64_REG_B2, IA64_REG_B3, IA64_REG_B4, IA64_REG_B5, 56 IA64_REG_F2, IA64_REG_F3, IA64_REG_F4, IA64_REG_F5, 57 IA64_REG_F16, IA64_REG_F17, IA64_REG_F18, IA64_REG_F19, 58 IA64_REG_F20, IA64_REG_F21, IA64_REG_F22, IA64_REG_F23, 59 IA64_REG_F24, IA64_REG_F25, IA64_REG_F26, IA64_REG_F27, 60 IA64_REG_F28, IA64_REG_F29, IA64_REG_F30, IA64_REG_F31, 61 IA64_NUM_PREGS 62 }; 63 64#ifdef UNW_LOCAL_ONLY 65 66typedef unw_word_t ia64_loc_t; 67 68#else /* !UNW_LOCAL_ONLY */ 69 70typedef struct ia64_loc 71 { 72 unw_word_t w0, w1; 73 } 74ia64_loc_t; 75 76#endif /* !UNW_LOCAL_ONLY */ 77 78#include "script.h" 79 80#define ABI_UNKNOWN 0 81#define ABI_LINUX 1 82#define ABI_HPUX 2 83#define ABI_FREEBSD 3 84#define ABI_OPENVMS 4 85#define ABI_NSK 5 /* Tandem/HP Non-Stop Kernel */ 86#define ABI_WINDOWS 6 87 88struct unw_addr_space 89 { 90 struct unw_accessors acc; 91 int big_endian; 92 int abi; /* abi < 0 => unknown, 0 => SysV, 1 => HP-UX, 2 => Windows */ 93 unw_caching_policy_t caching_policy; 94#ifdef HAVE_ATOMIC_OPS_H 95 AO_t cache_generation; 96#else 97 uint32_t cache_generation; 98#endif 99 unw_word_t dyn_generation; 100 unw_word_t dyn_info_list_addr; /* (cached) dyn_info_list_addr */ 101#ifndef UNW_REMOTE_ONLY 102 unsigned long long shared_object_removals; 103#endif 104 105 struct ia64_script_cache global_cache; 106 }; 107 108/* Note: The ABI numbers in the ABI-markers (.unwabi directive) are 109 not the same as the above ABI numbers. */ 110#define ABI_MARKER_OLD_LINUX_SIGTRAMP ((0 << 8) | 's') 111#define ABI_MARKER_OLD_LINUX_INTERRUPT ((0 << 8) | 'i') 112#define ABI_MARKER_HP_UX_SIGTRAMP ((1 << 8) | 1) 113#define ABI_MARKER_LINUX_SIGTRAMP ((3 << 8) | 's') 114#define ABI_MARKER_LINUX_INTERRUPT ((3 << 8) | 'i') 115 116struct cursor 117 { 118 void *as_arg; /* argument to address-space callbacks */ 119 unw_addr_space_t as; /* reference to per-address-space info */ 120 121 /* IP, CFM, and predicate cache (these are always equal to the 122 values stored in ip_loc, cfm_loc, and pr_loc, 123 respectively). */ 124 unw_word_t ip; /* instruction pointer value */ 125 unw_word_t cfm; /* current frame mask */ 126 unw_word_t pr; /* current predicate values */ 127 128 /* current frame info: */ 129 unw_word_t bsp; /* backing store pointer value */ 130 unw_word_t sp; /* stack pointer value */ 131 unw_word_t psp; /* previous sp value */ 132 ia64_loc_t cfm_loc; /* cfm save location (or NULL) */ 133 ia64_loc_t ec_loc; /* ar.ec save location (usually cfm_loc) */ 134 ia64_loc_t loc[IA64_NUM_PREGS]; 135 136 unw_word_t eh_args[4]; /* exception handler arguments */ 137 unw_word_t sigcontext_addr; /* address of sigcontext or 0 */ 138 unw_word_t sigcontext_off; /* sigcontext-offset relative to signal sp */ 139 140 short hint; 141 short prev_script; 142 143 uint8_t nat_bitnr[4]; /* NaT bit numbers for r4-r7 */ 144 uint16_t abi_marker; /* abi_marker for current frame (if any) */ 145 uint16_t last_abi_marker; /* last abi_marker encountered so far */ 146 uint8_t eh_valid_mask; 147 148 unsigned int pi_valid :1; /* is proc_info valid? */ 149 unsigned int pi_is_dynamic :1; /* proc_info found via dynamic proc info? */ 150 unw_proc_info_t pi; /* info about current procedure */ 151 152 /* In case of stack-discontiguities, such as those introduced by 153 signal-delivery on an alternate signal-stack (see 154 sigaltstack(2)), we use the following data-structure to keep 155 track of the register-backing-store areas across on which the 156 current frame may be backed up. Since there are at most 96 157 stacked registers and since we only have to track the current 158 frame and only areas that are not empty, this puts an upper 159 limit on the # of backing-store areas we have to track. 160 161 Note that the rbs-area indexed by rbs_curr identifies the 162 rbs-area that was in effect at the time AR.BSP had the value 163 c->bsp. However, this rbs area may not actually contain the 164 value in the register that c->bsp corresponds to because that 165 register may not have gotten spilled until much later, when a 166 possibly different rbs-area might have been in effect 167 already. */ 168 uint8_t rbs_curr; /* index of curr. rbs-area (contains c->bsp) */ 169 uint8_t rbs_left_edge; /* index of inner-most valid rbs-area */ 170 struct rbs_area 171 { 172 unw_word_t end; 173 unw_word_t size; 174 ia64_loc_t rnat_loc; 175 } 176 rbs_area[96 + 2]; /* 96 stacked regs + 1 extra stack on each side... */ 177}; 178 179struct ia64_global_unwind_state 180 { 181 pthread_mutex_t lock; /* global data lock */ 182 183 volatile char needs_initialization; 184 185 /* Table of registers that prologues can save (and order in which 186 they're saved). */ 187 const unsigned char save_order[8]; 188 189 /* 190 * uc_addr() may return pointers to these variables. We need to 191 * make sure they don't get written via ia64_put() or 192 * ia64_putfp(). To make it possible to test for these variables 193 * quickly, we collect them in a single sub-structure. 194 */ 195 struct 196 { 197 unw_word_t r0; /* r0 is byte-order neutral */ 198 unw_fpreg_t f0; /* f0 is byte-order neutral */ 199 unw_fpreg_t f1_le, f1_be; /* f1 is byte-order dependent */ 200 } 201 read_only; 202 unw_fpreg_t nat_val_le, nat_val_be; 203 unw_fpreg_t int_val_le, int_val_be; 204 205 struct mempool reg_state_pool; 206 struct mempool labeled_state_pool; 207 208# if UNW_DEBUG 209 const char *preg_name[IA64_NUM_PREGS]; 210# endif 211 }; 212 213#define tdep_needs_initialization unw.needs_initialization 214#define tdep_init UNW_OBJ(init) 215/* Platforms that support UNW_INFO_FORMAT_TABLE need to define 216 tdep_search_unwind_table. */ 217#define tdep_search_unwind_table unw_search_ia64_unwind_table 218#define tdep_find_proc_info UNW_OBJ(find_proc_info) 219#define tdep_uc_addr UNW_OBJ(uc_addr) 220#define tdep_get_elf_image UNW_ARCH_OBJ(get_elf_image) 221#define tdep_access_reg UNW_OBJ(access_reg) 222#define tdep_access_fpreg UNW_OBJ(access_fpreg) 223#define tdep_fetch_frame(c,ip,n) do {} while(0) 224#define tdep_cache_frame(c,rs) do {} while(0) 225#define tdep_reuse_frame(c,rs) do {} while(0) 226#define tdep_get_as(c) ((c)->as) 227#define tdep_get_as_arg(c) ((c)->as_arg) 228#define tdep_get_ip(c) ((c)->ip) 229#define tdep_big_endian(as) ((c)->as->big_endian != 0) 230 231#ifndef UNW_LOCAL_ONLY 232# define tdep_put_unwind_info UNW_OBJ(put_unwind_info) 233#endif 234 235/* This can't be an UNW_ARCH_OBJ() because we need separate 236 unw.initialized flags for the local-only and generic versions of 237 the library. Also, if we wanted to have a single, shared global 238 data structure, we couldn't declare "unw" as HIDDEN/PROTECTED. */ 239#define unw UNW_OBJ(data) 240 241extern void tdep_init (void); 242extern int tdep_find_proc_info (unw_addr_space_t as, unw_word_t ip, 243 unw_proc_info_t *pi, int need_unwind_info, 244 void *arg); 245extern void tdep_put_unwind_info (unw_addr_space_t as, 246 unw_proc_info_t *pi, void *arg); 247extern void *tdep_uc_addr (ucontext_t *uc, unw_regnum_t regnum, 248 uint8_t *nat_bitnr); 249extern int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, 250 unsigned long *segbase, unsigned long *mapoff); 251extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg, 252 unw_word_t *valp, int write); 253extern int tdep_access_fpreg (struct cursor *c, unw_regnum_t reg, 254 unw_fpreg_t *valp, int write); 255 256extern struct ia64_global_unwind_state unw; 257 258/* In user-level, we have no reasonable way of determining the base of 259 an arbitrary backing-store. We default to half the 260 address-space. */ 261#define rbs_get_base(c,bspstore,rbs_basep) \ 262 (*(rbs_basep) = (bspstore) - (((unw_word_t) 1) << 63), 0) 263 264#endif /* IA64_LIBUNWIND_I_H */ 265