Gregs.c revision a6ba57d5566681e68c0f9b6628be829f5a3dade1
1b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm/* libunwind - a platform-independent unwind library 23e00b79170aa5f641bb34b0e769c6c7485dab673mostang.com!davidm Copyright (C) 2001-2005 Hewlett-Packard Co 3b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 5b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmThis file is part of libunwind. 6b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 7b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmPermission is hereby granted, free of charge, to any person obtaining 8b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidma copy of this software and associated documentation files (the 9b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm"Software"), to deal in the Software without restriction, including 10b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmwithout limitation the rights to use, copy, modify, merge, publish, 11b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmdistribute, sublicense, and/or sell copies of the Software, and to 12b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmpermit persons to whom the Software is furnished to do so, subject to 13b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmthe following conditions: 14b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 15b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmThe above copyright notice and this permission notice shall be 16b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmincluded in all copies or substantial portions of the Software. 17b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 18b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 25b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 26b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#include <assert.h> 27b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#include <stddef.h> 28b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 29b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#include "offsets.h" 30b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#include "regs.h" 31b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#include "unwind_i.h" 32b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 33b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmstatic inline ia64_loc_t 34b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmlinux_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) 35b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{ 36b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#if !defined(UNW_LOCAL_ONLY) || defined(__linux) 37b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm unw_word_t addr = c->sigcontext_addr, flags, tmp_addr; 38b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm int i; 39b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 40b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (c->last_abi_marker == ABI_MARKER_LINUX_SIGTRAMP 41b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm || c->last_abi_marker == ABI_MARKER_OLD_LINUX_SIGTRAMP) 42b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 43b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm switch (reg) 44b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 45b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3: 46b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31: 47b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* Linux sigcontext contains the NaT bit of scratch register 48b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm N in bit position N of the sc_nat member. */ 49b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *nat_bitnr = (reg - UNW_IA64_NAT); 50b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_SC_NAT_OFF; 51b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 52b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 53b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: 54b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 8 ... UNW_IA64_GR + 31: 55b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_SC_GR_OFF + 8 * (reg - UNW_IA64_GR); 56b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 57b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 58b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15: 59b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_SC_FR_OFF + 16 * (reg - UNW_IA64_FR); 60b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); 61b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 62b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127: 63b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (ia64_get (c, IA64_LOC_ADDR (addr + LINUX_SC_FLAGS_OFF, 0), 64b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm &flags) < 0) 65b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_NULL_LOC; 66b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 67b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (!(flags & IA64_SC_FLAG_FPH_VALID)) 68b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 69b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* initialize fph partition: */ 70b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm tmp_addr = addr + LINUX_SC_FR_OFF + 32*16; 71b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm for (i = 32; i < 128; ++i, tmp_addr += 16) 72b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (ia64_putfp (c, IA64_LOC_ADDR (tmp_addr, 0), 73b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm unw.read_only.f0) < 0) 74b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_NULL_LOC; 75b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* mark fph partition as valid: */ 76b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (ia64_put (c, IA64_LOC_ADDR (addr + LINUX_SC_FLAGS_OFF, 0), 77b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm flags | IA64_SC_FLAG_FPH_VALID) < 0) 78b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_NULL_LOC; 79b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 80b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 81b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_SC_FR_OFF + 16 * (reg - UNW_IA64_FR); 82b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); 83b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 84b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 0: addr += LINUX_SC_BR_OFF + 0; break; 85b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 6: addr += LINUX_SC_BR_OFF + 6*8; break; 86b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 7: addr += LINUX_SC_BR_OFF + 7*8; break; 87b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_RSC: addr += LINUX_SC_AR_RSC_OFF; break; 88b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_CSD: addr += LINUX_SC_AR_CSD_OFF; break; 89b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_SSD: addr += LINUX_SC_AR_SSD_OFF; break; 90b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_CCV: addr += LINUX_SC_AR_CCV; break; 91b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 92b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm default: 93b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_REG_LOC (c, reg); 94b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 95b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_LOC_ADDR (addr, 0); 96b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 97b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 98b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 99b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm int is_nat = 0; 100b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 101b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if ((unsigned) (reg - UNW_IA64_NAT) < 128) 102b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 103b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm is_nat = 1; 104b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm reg -= (UNW_IA64_NAT - UNW_IA64_GR); 105b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 106b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (c->last_abi_marker == ABI_MARKER_LINUX_INTERRUPT) 107b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 108b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm switch (reg) 109b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 110b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 6 ... UNW_IA64_BR + 7: 111b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_PT_B6_OFF + 8 * (reg - (UNW_IA64_BR + 6)); 112b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 113b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 114b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_CSD: addr += LINUX_PT_CSD_OFF; break; 115b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_SSD: addr += LINUX_PT_SSD_OFF; break; 116b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 117b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 8 ... UNW_IA64_GR + 11: 118b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_PT_R8_OFF + 8 * (reg - (UNW_IA64_GR + 8)); 119b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 120b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 121b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_RSC: addr += LINUX_PT_RSC_OFF; break; 122b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 0: addr += LINUX_PT_B0_OFF; break; 123b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 1: addr += LINUX_PT_R1_OFF; break; 124b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 2: addr += LINUX_PT_R2_OFF; break; 125b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 3: addr += LINUX_PT_R3_OFF; break; 126b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 127b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 16 ... UNW_IA64_GR + 31: 128b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_PT_R16_OFF + 8 * (reg - (UNW_IA64_GR + 16)); 129b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 130b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 131b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_CCV: addr += LINUX_PT_CCV_OFF; break; 132b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 133b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 6 ... UNW_IA64_FR + 11: 134b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_PT_F6_OFF + 16 * (reg - (UNW_IA64_FR + 6)); 135b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); 136b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 137b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm default: 138b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_REG_LOC (c, reg); 139b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 140b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 141b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else if (c->last_abi_marker == ABI_MARKER_OLD_LINUX_INTERRUPT) 142b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 143b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm switch (reg) 144b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 145b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 1 ... UNW_IA64_GR + 3: 146b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_OLD_PT_R1_OFF + 8 * (reg - (UNW_IA64_GR + 1)); 147b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 148b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 149b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 8 ... UNW_IA64_GR + 11: 150b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_OLD_PT_R8_OFF + 8 * (reg - (UNW_IA64_GR + 8)); 151b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 152b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 153b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 16 ... UNW_IA64_GR + 31: 154b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_OLD_PT_R16_OFF + 8 * (reg - (UNW_IA64_GR + 16)); 155b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 156b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 157b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 6 ... UNW_IA64_FR + 9: 158b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm addr += LINUX_OLD_PT_F6_OFF + 16 * (reg - (UNW_IA64_FR + 6)); 159b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_LOC_ADDR (addr, IA64_LOC_TYPE_FP); 160b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 161b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 0: addr += LINUX_OLD_PT_B0_OFF; break; 162b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 6: addr += LINUX_OLD_PT_B6_OFF; break; 163b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 7: addr += LINUX_OLD_PT_B7_OFF; break; 164b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 165b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_RSC: addr += LINUX_OLD_PT_RSC_OFF; break; 166b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_CCV: addr += LINUX_OLD_PT_CCV_OFF; break; 167b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 168b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm default: 169b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_REG_LOC (c, reg); 170b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 171b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 172b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (is_nat) 173b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 174b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* For Linux pt-regs structure, bit number is determined by 175b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm the UNaT slot number (as determined by st8.spill) and the 176b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm bits are saved wherever the (primary) UNaT was saved. */ 177b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *nat_bitnr = ia64_unat_slot_num (addr); 178b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return c->loc[IA64_REG_PRI_UNAT_MEM]; 179b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 180b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_LOC_ADDR (addr, 0); 181b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 182b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#endif 183b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_NULL_LOC; 184b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm} 185b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 186b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmstatic inline ia64_loc_t 187b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmhpux_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) 188b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{ 189b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#if !defined(UNW_LOCAL_ONLY) || defined(__hpux) 190b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_LOC_UC_REG (reg, c->sigcontext_addr); 191b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#else 192b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_NULL_LOC; 193b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm#endif 194b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm} 195b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 196b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmHIDDEN ia64_loc_t 197b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmia64_scratch_loc (struct cursor *c, unw_regnum_t reg, uint8_t *nat_bitnr) 198b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{ 199b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (c->sigcontext_addr) 200b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 201b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (c->as->abi == ABI_LINUX) 202b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return linux_scratch_loc (c, reg, nat_bitnr); 203b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else if (c->as->abi == ABI_HPUX) 204b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return hpux_scratch_loc (c, reg, nat_bitnr); 205b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 206b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_NULL_LOC; 207b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 208b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 209b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return IA64_REG_LOC (c, reg); 210b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm} 211b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 212b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmstatic inline int 213b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmupdate_nat (struct cursor *c, ia64_loc_t nat_loc, unw_word_t mask, 214b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm unw_word_t *valp, int write) 215b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{ 216b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm unw_word_t nat_word; 217b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm int ret; 218b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 219b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ret = ia64_get (c, nat_loc, &nat_word); 220b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (ret < 0) 221b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ret; 222b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 223b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 224b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 225b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (*valp) 226b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm nat_word |= mask; 227b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 228b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm nat_word &= ~mask; 229b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ret = ia64_put (c, nat_loc, nat_word); 230b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 231b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 232b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = (nat_word & mask) != 0; 233b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ret; 234b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm} 235b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 236b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmstatic int 237b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmaccess_nat (struct cursor *c, 238b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ia64_loc_t nat_loc, ia64_loc_t reg_loc, uint8_t nat_bitnr, 239b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm unw_word_t *valp, int write) 240b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{ 241b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm unw_word_t mask = 0; 242b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm unw_fpreg_t tmp; 243b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm int ret; 244b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 245b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (IA64_IS_FP_LOC (reg_loc)) 246b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 247b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* NaT bit is saved as a NaTVal. This happens when a general 248b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm register is saved to a floating-point register. */ 249b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 250b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 251b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (*valp) 252b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 253b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (c->as->big_endian) 254b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ret = ia64_putfp (c, reg_loc, unw.nat_val_be); 255b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 256b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ret = ia64_putfp (c, reg_loc, unw.nat_val_le); 257b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 258b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 259b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 260b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm unw_fpreg_t tmp; 261b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 262b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ret = ia64_getfp (c, reg_loc, &tmp); 263b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (ret < 0) 264b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ret; 265b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 266b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* Reset the exponent to 0x1003e so that the significand 267b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm will be interpreted as an integer value. */ 268b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (c->as->big_endian) 269b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm tmp.raw.bits[0] = unw.int_val_be.raw.bits[0]; 270b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 271b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm tmp.raw.bits[1] = unw.int_val_le.raw.bits[1]; 272b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 273b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ret = ia64_putfp (c, reg_loc, tmp); 274b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 275b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 276b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 277b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 278b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ret = ia64_getfp (c, reg_loc, &tmp); 279b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (ret < 0) 280b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ret; 281b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 282b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (c->as->big_endian) 283b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = (memcmp (&tmp, &unw.nat_val_be, sizeof (tmp)) == 0); 284b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 285b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = (memcmp (&tmp, &unw.nat_val_le, sizeof (tmp)) == 0); 286b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 287b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ret; 288b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 289b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 290b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if ((IA64_IS_REG_LOC (nat_loc) 291b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm && (unsigned) (IA64_GET_REG (nat_loc) - UNW_IA64_NAT) < 128) 292b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm || IA64_IS_UC_LOC (reg_loc)) 293b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 294b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 295b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ia64_put (c, nat_loc, *valp); 296b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 297b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ia64_get (c, nat_loc, valp); 298b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 299b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 300b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (IA64_IS_NULL_LOC (nat_loc)) 301b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 302b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* NaT bit is not saved. This happens if a general register is 303b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm saved to a branch register. Since the NaT bit gets lost, we 304b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm need to drop it here, too. Note that if the NaT bit had been 305b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm set when the save occurred, it would have caused a NaT 306b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm consumption fault. */ 307b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 308b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 309b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (*valp) 310b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EBADREG; /* can't set NaT bit */ 311b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 312b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 313b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = 0; 314b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return 0; 315b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 316b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 317b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm mask = (unw_word_t) 1 << nat_bitnr; 318b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return update_nat (c, nat_loc, mask, valp, write); 319b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm} 320b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 321b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmHIDDEN int 322b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmtdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, 323b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm int write) 324b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{ 325b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ia64_loc_t loc, reg_loc, nat_loc; 326b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm int ret, readonly = 0; 327a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm unw_word_t nat, mask; 328b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm uint8_t nat_bitnr; 329b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 330b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm switch (reg) 331b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 332b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* frame registers: */ 333b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 334b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BSP: 335b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 336b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EREADONLYREG; 337b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = c->bsp; 338b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return 0; 339b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 340b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_REG_SP: 341b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 342b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EREADONLYREG; 343b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = c->sp; 344b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return 0; 345b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 346b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_REG_IP: 347b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 348b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 349b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm c->ip = *valp; /* also update the IP cache */ 350b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (c->pi_valid && (*valp < c->pi.start_ip || *valp >= c->pi.end_ip)) 351b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm c->pi_valid = 0; /* new IP outside of current proc */ 352b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 353b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm loc = c->loc[IA64_REG_IP]; 354b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 355b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 356b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* preserved registers: */ 357b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 358b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7: 359b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_GR + 4))]; 360b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 361b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 362b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_NAT + 4 ... UNW_IA64_NAT + 7: 363b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm loc = c->loc[IA64_REG_NAT4 + (reg - (UNW_IA64_NAT + 4))]; 364b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm reg_loc = c->loc[IA64_REG_R4 + (reg - (UNW_IA64_NAT + 4))]; 365b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm nat_bitnr = c->nat_bitnr[reg - (UNW_IA64_NAT + 4)]; 366b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return access_nat (c, loc, reg_loc, nat_bitnr, valp, write); 367b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 368b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_BSP: loc = c->loc[IA64_REG_BSP]; break; 369b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_BSPSTORE: loc = c->loc[IA64_REG_BSPSTORE]; break; 370b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_PFS: loc = c->loc[IA64_REG_PFS]; break; 371b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_RNAT: loc = c->loc[IA64_REG_RNAT]; break; 372b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_UNAT: loc = c->loc[IA64_REG_UNAT]; break; 373b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_LC: loc = c->loc[IA64_REG_LC]; break; 374b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_FPSR: loc = c->loc[IA64_REG_FPSR]; break; 375b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 1: loc = c->loc[IA64_REG_B1]; break; 376b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 2: loc = c->loc[IA64_REG_B2]; break; 377b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 3: loc = c->loc[IA64_REG_B3]; break; 378b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 4: loc = c->loc[IA64_REG_B4]; break; 379b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 5: loc = c->loc[IA64_REG_B5]; break; 380b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 381b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_CFM: 382b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 383b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm c->cfm = *valp; /* also update the CFM cache */ 384b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm loc = c->cfm_loc; 385b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 386b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 387b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_PR: 388a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm /* 389a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm * Note: broad-side access to the predicates is NOT rotated 390a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm * (i.e., it is done as if CFM.rrb.pr == 0. 391a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm */ 392b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 393b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 394b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm c->pr = *valp; /* update the predicate cache */ 395a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm return ia64_put (c, c->loc[IA64_REG_PR], *valp); 396b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 397b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 398a6ba57d5566681e68c0f9b6628be829f5a3dade1hp.com!davidm return ia64_get (c, c->loc[IA64_REG_PR], valp); 399b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 400b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 32 ... UNW_IA64_GR + 127: /* stacked reg */ 401b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm reg = rotate_gr (c, reg - UNW_IA64_GR); 402b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (reg < 0) 403b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EBADREG; 404b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ret = ia64_get_stacked (c, reg, &loc, NULL); 405b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (ret < 0) 406b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ret; 407b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 408b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 409b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_NAT + 32 ... UNW_IA64_NAT + 127: /* stacked reg */ 410b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm reg = rotate_gr (c, reg - UNW_IA64_NAT); 411b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (reg < 0) 412b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EBADREG; 413b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ret = ia64_get_stacked (c, reg, &loc, &nat_loc); 414b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (ret < 0) 415b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ret; 416b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm assert (!IA64_IS_REG_LOC (loc)); 4173e00b79170aa5f641bb34b0e769c6c7485dab673mostang.com!davidm mask = (unw_word_t) 1 << rse_slot_num (IA64_GET_ADDR (loc)); 418b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return update_nat (c, nat_loc, mask, valp, write); 419b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 420b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_EC: 421b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 422b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 423b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm c->cfm = ((c->cfm & ~((unw_word_t) 0x3f << 52)) 424b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm | ((*valp & 0x3f) << 52)); 425b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ia64_put (c, c->cfm_loc, c->cfm); 426b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 427b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 428b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 429b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = (c->cfm >> 52) & 0x3f; 430b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return 0; 431b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 432b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 433b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* scratch & special registers: */ 434b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 435b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 0: 436b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 437b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EREADONLYREG; 438b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = 0; 439b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return 0; 440b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 441b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 1: /* global pointer */ 442b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 443b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EREADONLYREG; 444b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 445b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* ensure c->pi is up-to-date: */ 446b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if ((ret = ia64_make_proc_info (c)) < 0) 447b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ret; 448b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = c->pi.gp; 449b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return 0; 450b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 451b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_NAT + 0: 452b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_NAT + 1: /* global pointer */ 453b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 454b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EREADONLYREG; 455b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = 0; 456b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return 0; 457b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 458b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_NAT + 2 ... UNW_IA64_NAT + 3: 459b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_NAT + 8 ... UNW_IA64_NAT + 31: 460b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm loc = ia64_scratch_loc (c, reg, &nat_bitnr); 461b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (!(IA64_IS_REG_LOC (loc) || IA64_IS_UC_LOC (loc) 462b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm || IA64_IS_FP_LOC (loc))) 463b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 464b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm /* We're dealing with a NaT bit stored in memory. */ 465b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm mask = (unw_word_t) 1 << nat_bitnr; 466b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 467b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if ((ret = ia64_get (c, loc, &nat)) < 0) 468b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ret; 469b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 470b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 471b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 472b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (*valp) 473b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm nat |= mask; 474b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 475b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm nat &= ~mask; 476b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ret = ia64_put (c, loc, nat); 477b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 478b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 479b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = (nat & mask) != 0; 480b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ret; 481b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 482b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 483b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 484b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 15 ... UNW_IA64_GR + 18: 485b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm mask = 1 << (reg - (UNW_IA64_GR + 15)); 486b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 487b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 488b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm c->eh_args[reg - (UNW_IA64_GR + 15)] = *valp; 489b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm c->eh_valid_mask |= mask; 490b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return 0; 491b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 492b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else if ((c->eh_valid_mask & mask) != 0) 493b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 4943e00b79170aa5f641bb34b0e769c6c7485dab673mostang.com!davidm *valp = c->eh_args[reg - (UNW_IA64_GR + 15)]; 495b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return 0; 496b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 497b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 498b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm loc = ia64_scratch_loc (c, reg, NULL); 499b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 500b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 501b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 2 ... UNW_IA64_GR + 3: 502b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 8 ... UNW_IA64_GR + 14: 503b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_GR + 19 ... UNW_IA64_GR + 31: 504b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 0: 505b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 6: 506b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_BR + 7: 507b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_RSC: 508b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_CSD: 509b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_SSD: 510b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_AR_CCV: 511b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm loc = ia64_scratch_loc (c, reg, NULL); 512b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 513b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 514b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm default: 515b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm Debug (1, "bad register number %d\n", reg); 516b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EBADREG; 517b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 518b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 519b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 520b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 521b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (readonly) 522b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EREADONLYREG; 523b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ia64_put (c, loc, *valp); 524b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 525b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 526b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ia64_get (c, loc, valp); 527b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm} 528b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 529b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmHIDDEN int 530b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidmtdep_access_fpreg (struct cursor *c, int reg, unw_fpreg_t *valp, 531b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm int write) 532b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm{ 533b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm ia64_loc_t loc; 534b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 535b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm switch (reg) 536b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm { 537b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 0: 538b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 539b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EREADONLYREG; 540b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = unw.read_only.f0; 541b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return 0; 542b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 543b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 1: 544b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 545b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EREADONLYREG; 546b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 547b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (c->as->big_endian) 548b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = unw.read_only.f1_be; 549b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 550b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm *valp = unw.read_only.f1_le; 551b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return 0; 552b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 553b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 2: loc = c->loc[IA64_REG_F2]; break; 554b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 3: loc = c->loc[IA64_REG_F3]; break; 555b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 4: loc = c->loc[IA64_REG_F4]; break; 556b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 5: loc = c->loc[IA64_REG_F5]; break; 557b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 558b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31: 559b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm loc = c->loc[IA64_REG_F16 + (reg - (UNW_IA64_FR + 16))]; 560b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 561b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 562b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 6 ... UNW_IA64_FR + 15: 563b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm loc = ia64_scratch_loc (c, reg, NULL); 564b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 565b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 566b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm case UNW_IA64_FR + 32 ... UNW_IA64_FR + 127: 567b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm reg = rotate_fr (c, reg - UNW_IA64_FR) + UNW_IA64_FR; 568b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm loc = ia64_scratch_loc (c, reg, NULL); 569b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm break; 570b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 571b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm default: 572b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm Debug (1, "bad register number %d\n", reg); 573b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return -UNW_EBADREG; 574b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm } 575b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm 576b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm if (write) 577b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ia64_putfp (c, loc, *valp); 578b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm else 579b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm return ia64_getfp (c, loc, valp); 580b3f681603b67e00cd04833e9f85c4a3adf027cc2homeip.net!davidm} 581