16607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm/* libunwind - a platform-independent unwind library 26607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm Copyright (c) 2002-2004 Hewlett-Packard Development Company, L.P. 36607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 46607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 56607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmThis file is part of libunwind. 66607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 76607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmPermission is hereby granted, free of charge, to any person obtaining 86607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidma copy of this software and associated documentation files (the 96607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm"Software"), to deal in the Software without restriction, including 106607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmwithout limitation the rights to use, copy, modify, merge, publish, 116607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmdistribute, sublicense, and/or sell copies of the Software, and to 126607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmpermit persons to whom the Software is furnished to do so, subject to 136607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmthe following conditions: 146607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 156607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmThe above copyright notice and this permission notice shall be 166607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmincluded in all copies or substantial portions of the Software. 176607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 186607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 196607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 206607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 216607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 226607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 236607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 246607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 256607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 266607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm#include "offsets.h" 276607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm#include "unwind_i.h" 286607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 296607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmHIDDEN dwarf_loc_t 306607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmx86_scratch_loc (struct cursor *c, unw_regnum_t reg) 316607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm{ 326607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm if (c->sigcontext_addr) 3379d012348df333f191fcb10789dad12b655f2baaKonstantin Belousov return x86_get_scratch_loc (c, reg); 346607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm else 356607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm return DWARF_REG_LOC (&c->dwarf, reg); 366607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm} 376607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 386607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmHIDDEN int 396607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmtdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, 406607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm int write) 416607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm{ 426607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm dwarf_loc_t loc = DWARF_NULL_LOC; 43db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm unsigned int mask; 44db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm int arg_num; 456607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 466607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm switch (reg) 476607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm { 486607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 496607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_EIP: 506607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm if (write) 516607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm c->dwarf.ip = *valp; /* also update the EIP cache */ 526607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm loc = c->dwarf.loc[EIP]; 536607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm break; 546607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 556607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_CFA: 56db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm case UNW_X86_ESP: 576607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm if (write) 586607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm return -UNW_EREADONLYREG; 596607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm *valp = c->dwarf.cfa; 606607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm return 0; 616607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 62db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm case UNW_X86_EAX: 63db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm case UNW_X86_EDX: 64db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm arg_num = reg - UNW_X86_EAX; 65db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm mask = (1 << arg_num); 66db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm if (write) 67db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm { 68db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm c->dwarf.eh_args[arg_num] = *valp; 69db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm c->dwarf.eh_valid_mask |= mask; 70db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm return 0; 71db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm } 72db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm else if ((c->dwarf.eh_valid_mask & mask) != 0) 73be2bed2712097dae6d44bb1a9d46da2b0c17db4ahomeip.net!davidm { 74db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm *valp = c->dwarf.eh_args[arg_num]; 75be2bed2712097dae6d44bb1a9d46da2b0c17db4ahomeip.net!davidm return 0; 76be2bed2712097dae6d44bb1a9d46da2b0c17db4ahomeip.net!davidm } 77db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm else 78db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm loc = c->dwarf.loc[(reg == UNW_X86_EAX) ? EAX : EDX]; 79be2bed2712097dae6d44bb1a9d46da2b0c17db4ahomeip.net!davidm break; 80db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm 81db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break; 82db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break; 83db1517609c217734dd5ef0bbc133cd2f23bb4465mostang.com!davidm 846607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break; 856607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break; 866607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break; 876607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_EFLAGS: loc = c->dwarf.loc[EFLAGS]; break; 886607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_TRAPNO: loc = c->dwarf.loc[TRAPNO]; break; 896607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 906607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_FCW: 916607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_FSW: 926607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_FTW: 936607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_FOP: 946607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_FCS: 956607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_FIP: 966607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_FEA: 976607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_FDS: 986607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_MXCSR: 996607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_GS: 1006607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_FS: 1016607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_ES: 1026607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_DS: 1036607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_SS: 1046607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_CS: 1056607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_TSS: 1066607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_LDT: 1076607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm loc = x86_scratch_loc (c, reg); 1086607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm break; 1096607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 1106607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm default: 1116607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm Debug (1, "bad register number %u\n", reg); 1126607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm return -UNW_EBADREG; 1136607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm } 1146607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 1156607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm if (write) 1166607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm return dwarf_put (&c->dwarf, loc, *valp); 1176607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm else 1186607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm return dwarf_get (&c->dwarf, loc, valp); 1196607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm} 1206607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 1216607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmHIDDEN int 1226607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidmtdep_access_fpreg (struct cursor *c, unw_regnum_t reg, unw_fpreg_t *valp, 1236607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm int write) 1246607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm{ 1256607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm struct dwarf_loc loc = DWARF_NULL_LOC; 1266607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 1276607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm switch (reg) 1286607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm { 1296607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_ST0: 1306607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm loc = c->dwarf.loc[ST0]; 1316607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm break; 1326607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 1336607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm /* stacked fp registers */ 1346607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_ST1: 1356607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_ST2: 1366607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_ST3: 1376607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_ST4: 1386607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_ST5: 1396607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_ST6: 1406607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_ST7: 1416607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm /* SSE fp registers */ 142a8be10e2518fe41fbbfc7cd277a170c5f8ab5b39David Mosberger-Tang case UNW_X86_XMM0: 143a8be10e2518fe41fbbfc7cd277a170c5f8ab5b39David Mosberger-Tang case UNW_X86_XMM1: 144a8be10e2518fe41fbbfc7cd277a170c5f8ab5b39David Mosberger-Tang case UNW_X86_XMM2: 145a8be10e2518fe41fbbfc7cd277a170c5f8ab5b39David Mosberger-Tang case UNW_X86_XMM3: 146a8be10e2518fe41fbbfc7cd277a170c5f8ab5b39David Mosberger-Tang case UNW_X86_XMM4: 147a8be10e2518fe41fbbfc7cd277a170c5f8ab5b39David Mosberger-Tang case UNW_X86_XMM5: 148a8be10e2518fe41fbbfc7cd277a170c5f8ab5b39David Mosberger-Tang case UNW_X86_XMM6: 149a8be10e2518fe41fbbfc7cd277a170c5f8ab5b39David Mosberger-Tang case UNW_X86_XMM7: 1506607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM0_lo: 1516607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM0_hi: 1526607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM1_lo: 1536607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM1_hi: 1546607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM2_lo: 1556607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM2_hi: 1566607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM3_lo: 1576607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM3_hi: 1586607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM4_lo: 1596607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM4_hi: 1606607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM5_lo: 1616607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM5_hi: 1626607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM6_lo: 1636607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM6_hi: 1646607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM7_lo: 1656607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm case UNW_X86_XMM7_hi: 1666607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm loc = x86_scratch_loc (c, reg); 1676607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm break; 1686607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 1696607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm default: 1706607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm Debug (1, "bad register number %u\n", reg); 1716607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm return -UNW_EBADREG; 1726607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm } 1736607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm 1746607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm if (write) 1756607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm return dwarf_putfp (&c->dwarf, loc, *valp); 1766607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm else 1776607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm return dwarf_getfp (&c->dwarf, loc, valp); 1786607424863ecedc32f3a3030a623fb19b61b16e3homeip.net!davidm} 179