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>
This commit is contained in:
Elliott Hughes 2014-02-28 23:21:35 +00:00 committed by Dmitry V. Levin
parent fb642bb6d6
commit 458b3f2fd9

View File

@ -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;
}