diff --git a/include/dwarf_i.h b/include/dwarf_i.h new file mode 100644 index 00000000..55320c2d --- /dev/null +++ b/include/dwarf_i.h @@ -0,0 +1,343 @@ +#ifndef DWARF_I_H +#define DWARF_I_H + +/* This file contains definitions that cannot be used in code outside + of libunwind. In particular, most inline functions are here + because otherwise they'd generate unresolved references when the + files are compiled with inlining disabled. */ + +#include "dwarf.h" +#include "tdep.h" + +#define dwarf_to_unw_regnum_map UNW_OBJ (dwarf_to_unw_regnum_map) + +extern uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH]; + +static inline unw_regnum_t +dwarf_to_unw_regnum (unw_word_t regnum) +{ + if (regnum <= DWARF_REGNUM_MAP_LENGTH) + return dwarf_to_unw_regnum_map[regnum]; + return 0; +} + +#ifdef UNW_LOCAL_ONLY + +/* In the local-only case, we can let the compiler directly access + memory and don't need to worry about differing byte-order. */ + +typedef union + { + int8_t s8; + int16_t s16; + int32_t s32; + int64_t s64; + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; + unw_word_t w; + void *ptr; + } +dwarf_misaligned_value_t __attribute__ ((packed)); + +static inline int +dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int8_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) *addr; + + *val = mvp->s8; + *addr += sizeof (mvp->s8); + return 0; +} + +static inline int +dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int16_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) *addr; + + *val = mvp->s16; + *addr += sizeof (mvp->s16); + return 0; +} + +static inline int +dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int32_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) *addr; + + *val = mvp->s32; + *addr += sizeof (mvp->s32); + return 0; +} + +static inline int +dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int64_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) *addr; + + *val = mvp->s64; + *addr += sizeof (mvp->s64); + return 0; +} + +static inline int +dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint8_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) *addr; + + *val = mvp->u8; + *addr += sizeof (mvp->u8); + return 0; +} + +static inline int +dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint16_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) *addr; + + *val = mvp->u16; + *addr += sizeof (mvp->u16); + return 0; +} + +static inline int +dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint32_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) *addr; + + *val = mvp->u32; + *addr += sizeof (mvp->u32); + return 0; +} + +static inline int +dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint64_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) *addr; + + *val = mvp->u64; + *addr += sizeof (mvp->u64); + return 0; +} + +static inline int +dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + unw_word_t *val, void *arg) +{ + dwarf_misaligned_value_t *mvp = (void *) *addr; + + *val = mvp->w; + *addr += sizeof (mvp->w); + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ + +static inline int +dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint8_t *valp, void *arg) +{ + unw_word_t val, aligned_addr = *addr & -sizeof (unw_word_t); + unw_word_t off = *addr - aligned_addr; + int ret; + + *addr += 1; + ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); +#if __BYTE_ORDER == __LITTLE_ENDIAN + val >>= 8*off; +#else + val >>= 8*(sizeof (unw_word_t) - 1 - off); +#endif + *valp = (uint8_t) val; + return ret; +} + +static inline int +dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint16_t *val, void *arg) +{ + uint8_t v0, v1; + int ret; + + if ((ret = dwarf_readu8 (as, a, addr, &v0, arg)) < 0 + || (ret = dwarf_readu8 (as, a, addr, &v1, arg)) < 0) + return ret; + + if (tdep_big_endian (as)) + *val = (uint16_t) v0 << 8 | v1; + else + *val = (uint16_t) v1 << 8 | v0; + return 0; +} + +static inline int +dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint32_t *val, void *arg) +{ + uint16_t v0, v1; + int ret; + + if ((ret = dwarf_readu16 (as, a, addr, &v0, arg)) < 0 + || (ret = dwarf_readu16 (as, a, addr, &v1, arg)) < 0) + return ret; + + if (tdep_big_endian (as)) + *val = (uint32_t) v0 << 16 | v1; + else + *val = (uint32_t) v1 << 16 | v0; + return 0; +} + +static inline int +dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + uint64_t *val, void *arg) +{ + uint32_t v0, v1; + int ret; + + if ((ret = dwarf_readu32 (as, a, addr, &v0, arg)) < 0 + || (ret = dwarf_readu32 (as, a, addr, &v1, arg)) < 0) + return ret; + + if (tdep_big_endian (as)) + *val = (uint64_t) v0 << 32 | v1; + else + *val = (uint64_t) v1 << 32 | v0; + return 0; +} + +static inline int +dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int8_t *val, void *arg) +{ + uint8_t uval; + int ret; + + if ((ret = dwarf_readu8 (as, a, addr, &uval, arg)) < 0) + return ret; + *val = (int8_t) uval; + return 0; +} + +static inline int +dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int16_t *val, void *arg) +{ + uint16_t uval; + int ret; + + if ((ret = dwarf_readu16 (as, a, addr, &uval, arg)) < 0) + return ret; + *val = (int16_t) uval; + return 0; +} + +static inline int +dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int32_t *val, void *arg) +{ + uint32_t uval; + int ret; + + if ((ret = dwarf_readu32 (as, a, addr, &uval, arg)) < 0) + return ret; + *val = (int32_t) uval; + return 0; +} + +static inline int +dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + int64_t *val, void *arg) +{ + uint64_t uval; + int ret; + + if ((ret = dwarf_readu64 (as, a, addr, &uval, arg)) < 0) + return ret; + *val = (int64_t) uval; + return 0; +} + +static inline int +dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + unw_word_t *val, void *arg) +{ + switch (sizeof (unw_word_t)) + { + case 4: + return dwarf_readu32 (as, a, addr, (uint32_t *) val, arg); + + case 8: + return dwarf_readu64 (as, a, addr, (uint64_t *) val, arg); + + default: + abort (); + } +} + +#endif /* !UNW_LOCAL_ONLY */ + +/* Read an unsigned "little-endian base 128" value. See Chapter 7.6 + of DWARF spec v3. */ + +static inline int +dwarf_read_uleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + unw_word_t *valp, void *arg) +{ + unw_word_t val = 0, shift = 0; + unsigned char byte; + int ret; + + do + { + if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0) + return ret; + + val |= ((unw_word_t) byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + *valp = val; + return 0; +} + +/* Read a signed "little-endian base 128" value. See Chapter 7.6 of + DWARF spec v3. */ + +static inline int +dwarf_read_sleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, + unw_word_t *valp, void *arg) +{ + unw_word_t val = 0, shift = 0; + unsigned char byte; + int ret; + + do + { + if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0) + return ret; + + val |= ((unw_word_t) byte & 0x7f) << shift; + shift += 7; + } + while (byte & 0x80); + + if (shift < 8 * sizeof (unw_word_t) && (byte & 0x40) != 0) + /* sign-extend negative value */ + val |= ((unw_word_t) -1) << shift; + + *valp = val; + return 0; +} + +#endif /* DWARF_I_H */ diff --git a/include/remote.h b/include/remote.h new file mode 100644 index 00000000..a5ecab95 --- /dev/null +++ b/include/remote.h @@ -0,0 +1,127 @@ +#ifndef REMOTE_H +#define REMOTE_H + +/* Helper functions for accessing (remote) memory. These functions + assume that all addresses are naturally aligned (e.g., 32-bit + quantity is stored at a 32-bit-aligned address. */ + +#ifdef UNW_LOCAL_ONLY + +static inline int +fetch8 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int8_t *valp, void *arg) +{ + *valp = *(int8_t *) *addr; + *addr += 1; + return 0; +} + +static inline int +fetch16 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int16_t *valp, void *arg) +{ + *valp = *(int16_t *) *addr; + *addr += 2; + return 0; +} + +static inline int +fetch32 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int32_t *valp, void *arg) +{ + *valp = *(int32_t *) *addr; + *addr += 4; + return 0; +} + +static inline int +fetchw (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_word_t *valp, void *arg) +{ + *valp = *(unw_word_t *) *addr; + *addr += sizeof (unw_word_t); + return 0; +} + +#else /* !UNW_LOCAL_ONLY */ + +#define WSIZE (sizeof (unw_word_t)) + +static inline int +fetch8 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int8_t *valp, void *arg) +{ + unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; + int ret; + + *addr += 1; + + ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); + +#if __BYTE_ORDER == __LITTLE_ENDIAN + val >>= 8*off; +#else + val >>= 8*(WSIZE - 1 - off); +#endif + *valp = val & 0xff; + return ret; +} + +static inline int +fetch16 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int16_t *valp, void *arg) +{ + unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; + int ret; + + assert ((off & 0x1) == 0); + + *addr += 2; + + ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); + +#if __BYTE_ORDER == __LITTLE_ENDIAN + val >>= 8*off; +#else + val >>= 8*(WSIZE - 2 - off); +#endif + *valp = val & 0xffff; + return ret; +} + +static inline int +fetch32 (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, int32_t *valp, void *arg) +{ + unw_word_t val, aligned_addr = *addr & -WSIZE, off = *addr - aligned_addr; + int ret; + + assert ((off & 0x3) == 0); + + *addr += 4; + + ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg); + +#if __BYTE_ORDER == __LITTLE_ENDIAN + val >>= 8*off; +#else + val >>= 8*(WSIZE - 4 - off); +#endif + *valp = val & 0xffffffff; + return ret; +} + +static inline int +fetchw (unw_addr_space_t as, unw_accessors_t *a, + unw_word_t *addr, unw_word_t *valp, void *arg) +{ + int ret; + + ret = (*a->access_mem) (as, *addr, valp, 0, arg); + *addr += WSIZE; + return ret; +} + +#endif /* !UNW_LOCAL_ONLY */ + +#endif /* REMOTE_H */ diff --git a/src/mi/Gget_fpreg.c b/src/mi/Gget_fpreg.c new file mode 100644 index 00000000..8ff69d23 --- /dev/null +++ b/src/mi/Gget_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "tdep.h" + +PROTECTED int +unw_get_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t *valp) +{ + struct cursor *c = (struct cursor *) cursor; + + return tdep_access_fpreg (c, regnum, valp, 0); +} diff --git a/src/mi/Gset_fpreg.c b/src/mi/Gset_fpreg.c new file mode 100644 index 00000000..05e1c16a --- /dev/null +++ b/src/mi/Gset_fpreg.c @@ -0,0 +1,34 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "tdep.h" + +PROTECTED int +unw_set_fpreg (unw_cursor_t *cursor, int regnum, unw_fpreg_t val) +{ + struct cursor *c = (struct cursor *) cursor; + + return tdep_access_fpreg (c, regnum, &val, 1); +} diff --git a/src/mi/Ldestroy_addr_space.c b/src/mi/Ldestroy_addr_space.c new file mode 100644 index 00000000..5bf9364b --- /dev/null +++ b/src/mi/Ldestroy_addr_space.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gdestroy_addr_space.c" +#endif diff --git a/src/mi/Ldyn-remote.c b/src/mi/Ldyn-remote.c new file mode 100644 index 00000000..260722a0 --- /dev/null +++ b/src/mi/Ldyn-remote.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gdyn-remote.c" +#endif diff --git a/src/mi/Lget_accessors.c b/src/mi/Lget_accessors.c new file mode 100644 index 00000000..555e37f3 --- /dev/null +++ b/src/mi/Lget_accessors.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_accessors.c" +#endif diff --git a/src/mi/Lget_fpreg.c b/src/mi/Lget_fpreg.c new file mode 100644 index 00000000..e3be4414 --- /dev/null +++ b/src/mi/Lget_fpreg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_fpreg.c" +#endif diff --git a/src/mi/Lget_reg.c b/src/mi/Lget_reg.c new file mode 100644 index 00000000..effe8a80 --- /dev/null +++ b/src/mi/Lget_reg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_reg.c" +#endif diff --git a/src/mi/Lset_caching_policy.c b/src/mi/Lset_caching_policy.c new file mode 100644 index 00000000..cc18816b --- /dev/null +++ b/src/mi/Lset_caching_policy.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gset_caching_policy.c" +#endif diff --git a/src/mi/Lset_fpreg.c b/src/mi/Lset_fpreg.c new file mode 100644 index 00000000..2497d404 --- /dev/null +++ b/src/mi/Lset_fpreg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gset_fpreg.c" +#endif diff --git a/src/mi/Lset_reg.c b/src/mi/Lset_reg.c new file mode 100644 index 00000000..c7a872b0 --- /dev/null +++ b/src/mi/Lset_reg.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gset_reg.c" +#endif diff --git a/src/x86/Gget_save_loc-x86.c b/src/x86/Gget_save_loc-x86.c new file mode 100644 index 00000000..1bd3560c --- /dev/null +++ b/src/x86/Gget_save_loc-x86.c @@ -0,0 +1,125 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2004 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "unwind_i.h" + +PROTECTED int +unw_get_save_loc (unw_cursor_t *cursor, int reg, unw_save_loc_t *sloc) +{ + struct cursor *c = (struct cursor *) cursor; + dwarf_loc_t loc; + + loc = DWARF_NULL_LOC; /* default to "not saved" */ + + switch (reg) + { + case UNW_X86_EIP: loc = c->dwarf.loc[EIP]; break; + case UNW_X86_CFA: break; + case UNW_X86_EAX: loc = c->dwarf.loc[EAX]; break; + case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break; + case UNW_X86_EDX: loc = c->dwarf.loc[EDX]; break; + case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break; + case UNW_X86_ESP: loc = c->dwarf.loc[ESP]; break; + case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break; + case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break; + case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break; + case UNW_X86_EFLAGS: loc = c->dwarf.loc[EFLAGS]; break; + case UNW_X86_TRAPNO: loc = c->dwarf.loc[TRAPNO]; break; + case UNW_X86_ST0: loc = c->dwarf.loc[ST0]; break; + + case UNW_X86_FCW: + case UNW_X86_FSW: + case UNW_X86_FTW: + case UNW_X86_FOP: + case UNW_X86_FCS: + case UNW_X86_FIP: + case UNW_X86_FEA: + case UNW_X86_FDS: + case UNW_X86_MXCSR: + case UNW_X86_GS: + case UNW_X86_FS: + case UNW_X86_ES: + case UNW_X86_DS: + case UNW_X86_SS: + case UNW_X86_CS: + case UNW_X86_TSS: + case UNW_X86_LDT: + loc = x86_scratch_loc (c, reg); + break; + + /* stacked fp registers */ + case UNW_X86_ST1: + case UNW_X86_ST2: + case UNW_X86_ST3: + case UNW_X86_ST4: + case UNW_X86_ST5: + case UNW_X86_ST6: + case UNW_X86_ST7: + /* SSE fp registers */ + case UNW_X86_XMM0_lo: + case UNW_X86_XMM0_hi: + case UNW_X86_XMM1_lo: + case UNW_X86_XMM1_hi: + case UNW_X86_XMM2_lo: + case UNW_X86_XMM2_hi: + case UNW_X86_XMM3_lo: + case UNW_X86_XMM3_hi: + case UNW_X86_XMM4_lo: + case UNW_X86_XMM4_hi: + case UNW_X86_XMM5_lo: + case UNW_X86_XMM5_hi: + case UNW_X86_XMM6_lo: + case UNW_X86_XMM6_hi: + case UNW_X86_XMM7_lo: + case UNW_X86_XMM7_hi: + loc = x86_scratch_loc (c, reg); + break; + + default: + break; + } + + memset (sloc, 0, sizeof (sloc)); + + if (DWARF_IS_NULL_LOC (loc)) + { + sloc->type = UNW_SLT_NONE; + return 0; + } + +#if !defined(UNW_LOCAL_ONLY) + if (DWARF_IS_REG_LOC (loc)) + { + sloc->type = UNW_SLT_REG; + sloc->u.regnum = DWARF_GET_LOC (loc); + } + else +#endif + { + sloc->type = UNW_SLT_MEMORY; + sloc->u.addr = DWARF_GET_LOC (loc); + } + return 0; +} diff --git a/src/x86/Lget_save_loc-x86.c b/src/x86/Lget_save_loc-x86.c new file mode 100644 index 00000000..46b6d3ed --- /dev/null +++ b/src/x86/Lget_save_loc-x86.c @@ -0,0 +1,5 @@ +#define UNW_LOCAL_ONLY +#include +#if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY) +#include "Gget_save_loc-x86.c" +#endif