summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2014-02-28 23:21:35 +0000
committerDmitry V. Levin <ldv@altlinux.org>2014-02-28 23:35:21 +0000
commit458b3f2fd964d23cf779c235ecb2b8f1c40d994c (patch)
tree91199c2ce5a7a8f68a0b3d40695f6428afcfc3b0
parentfb642bb6d63f7ffe2228bf48a6008bc8f56f67ff (diff)
downloadstrace-458b3f2fd964d23cf779c235ecb2b8f1c40d994c.tar.gz
strace-458b3f2fd964d23cf779c235ecb2b8f1c40d994c.tar.bz2
strace-458b3f2fd964d23cf779c235ecb2b8f1c40d994c.tar.xz
Add multi-personality support to struct old_sigaction decoding
struct sigaction is another structure that contains members whose size differs between 32-bit and 64-bit personalities. * signal.c [HAVE_SIGACTION] (old_sigaction32): New structure. [HAVE_SIGACTION] (decode_old_sigaction): Decode 32-bit struct old_sigaction on a 64-bit host. Signed-off-by: Elliott Hughes <enh@google.com>
-rw-r--r--signal.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/signal.c b/signal.c
index 436039b..ce8ec0a 100644
--- a/signal.c
+++ b/signal.c
@@ -691,10 +691,19 @@ struct old_sigaction {
#endif /* !MIPS */
};
+struct old_sigaction32 {
+ /* sa_handler may be a libc #define, need to use other name: */
+ uint32_t __sa_handler;
+ uint32_t sa_mask;
+ uint32_t sa_flags;
+ uint32_t sa_restorer;
+};
+
static void
decode_old_sigaction(struct tcb *tcp, long addr)
{
struct old_sigaction sa;
+ int r;
if (!addr) {
tprints("NULL");
@@ -704,7 +713,24 @@ decode_old_sigaction(struct tcb *tcp, long addr)
tprintf("%#lx", addr);
return;
}
- if (umove(tcp, addr, &sa) < 0) {
+
+#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
+ if (current_wordsize != sizeof(sa.__sa_handler) && current_wordsize == 4) {
+ struct old_sigaction32 sa32;
+ r = umove(tcp, addr, &sa32);
+ if (r >= 0) {
+ memset(&sa, 0, sizeof(sa));
+ sa.__sa_handler = (void*)(uintptr_t)sa32.__sa_handler;
+ sa.sa_flags = sa32.sa_flags;
+ sa.sa_restorer = (void*)(uintptr_t)sa32.sa_restorer;
+ sa.sa_mask = sa32.sa_mask;
+ }
+ } else
+#endif
+ {
+ r = umove(tcp, addr, &sa);
+ }
+ if (r < 0) {
tprints("{...}");
return;
}