diff options
author | Dmitry V. Levin <ldv@altlinux.org> | 2014-02-26 22:29:27 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2014-02-27 22:35:39 +0000 |
commit | d153bfc505dd30dabc2509091e67460c3ca1675b (patch) | |
tree | c40bc0ca23e3abbf2384fada792f723812810d1f | |
parent | 38593e942ad4b16b2c3c43ea521167368771cbfb (diff) | |
download | strace-d153bfc505dd30dabc2509091e67460c3ca1675b.tar.gz strace-d153bfc505dd30dabc2509091e67460c3ca1675b.tar.bz2 strace-d153bfc505dd30dabc2509091e67460c3ca1675b.tar.xz |
Add multi-personality support to stack_t decoding
stack_t is one of many structures that contain members
whose size differs between 32-bit and 64-bit personalities.
* signal.c (print_stack_t): Decode 32-bit stack_t on a 64-bit host.
Reported-by: Elliott Hughes <enh@google.com>
-rw-r--r-- | signal.c | 25 |
1 files changed, 24 insertions, 1 deletions
@@ -1084,10 +1084,33 @@ static void print_stack_t(struct tcb *tcp, unsigned long addr) { stack_t ss; + int r; if (!addr) { tprints("NULL"); - } else if (umove(tcp, addr, &ss) < 0) { + return; + } + +#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 + if (current_wordsize != sizeof(ss.ss_sp) && current_wordsize == 4) { + struct { + uint32_t ss_sp; + int32_t ss_flags; + uint32_t ss_size; + } ss32; + r = umove(tcp, addr, &ss32); + if (r >= 0) { + memset(&ss, 0, sizeof(ss)); + ss.ss_sp = (void*)(unsigned long) ss32.ss_sp; + ss.ss_flags = ss32.ss_flags; + ss.ss_size = (unsigned long) ss32.ss_size; + } + } else +#endif + { + r = umove(tcp, addr, &ss); + } + if (r < 0) { tprintf("%#lx", addr); } else { tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp); |