#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 *) (uintptr_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 *) (uintptr_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 *) (uintptr_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 *) (uintptr_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 */