summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2014-02-26 22:29:27 +0000
committerDmitry V. Levin <ldv@altlinux.org>2014-02-27 22:35:39 +0000
commitd153bfc505dd30dabc2509091e67460c3ca1675b (patch)
treec40bc0ca23e3abbf2384fada792f723812810d1f
parent38593e942ad4b16b2c3c43ea521167368771cbfb (diff)
downloadstrace-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.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/signal.c b/signal.c
index a13f7ac..436039b 100644
--- a/signal.c
+++ b/signal.c
@@ -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);