* signal (sys_rt_sigaction): Print struct sigaction correctly

in 32/64 environment.
* desc.c (printflock): Add #ifdefs around earlier flock 32/64 fix
so that we don't waste time on arches with one personality.
This commit is contained in:
Denys Vlasenko 2009-04-15 13:22:59 +00:00
parent 1d632468c0
commit 7a862d7620
3 changed files with 121 additions and 65 deletions

View File

@ -1,3 +1,10 @@
2009-04-15 Denys Vlasenko <dvlasenk@redhat.com>
* signal (sys_rt_sigaction): Print struct sigaction correctly
in 32/64 environment.
* desc.c (printflock): Add #ifdefs around earlier flock 32/64 fix
so that we don't waste time on arches with one personality.
2009-04-14 Denys Vlasenko <dvlasenk@redhat.com>
* signal.c: Whitespace, comment, and style fixes, no code changes.

53
desc.c
View File

@ -236,34 +236,39 @@ printflock(struct tcb *tcp, long addr, int getlk)
{
struct flock fl;
if (personality_wordsize[current_personality] == sizeof(fl.l_start)) {
#if SUPPORTED_PERSONALITIES > 1
if (personality_wordsize[current_personality] != sizeof(fl.l_start)) {
if (personality_wordsize[current_personality] == 4) {
/* 32-bit x86 app on x86_64 and similar cases */
struct {
short int l_type;
short int l_whence;
int32_t l_start; /* off_t */
int32_t l_len; /* off_t */
int32_t l_pid; /* pid_t */
} fl32;
if (umove(tcp, addr, &fl32) < 0) {
tprintf("{...}");
return;
}
fl.l_type = fl32.l_type;
fl.l_whence = fl32.l_whence;
fl.l_start = fl32.l_start;
fl.l_len = fl32.l_len;
fl.l_pid = fl32.l_pid;
} else {
/* let people know we have a problem here */
tprintf("{ <decode error: unsupported wordsize %d> }",
personality_wordsize[current_personality]);
return;
}
} else
#endif
{
if (umove(tcp, addr, &fl) < 0) {
tprintf("{...}");
return;
}
} else if (personality_wordsize[current_personality] == 4) {
/* 32-bit x86 app on x86_64 and similar cases */
struct {
short int l_type;
short int l_whence;
int32_t l_start; /* off_t */
int32_t l_len; /* off_t */
int32_t l_pid; /* pid_t */
} fl32;
if (umove(tcp, addr, &fl32) < 0) {
tprintf("{...}");
return;
}
fl.l_type = fl32.l_type;
fl.l_whence = fl32.l_whence;
fl.l_start = fl32.l_start;
fl.l_len = fl32.l_len;
fl.l_pid = fl32.l_pid;
} else {
/* let people know we have a problem here */
tprintf("{ <decode error: unsupported wordsize %d> }",
personality_wordsize[current_personality]);
return;
}
tprintf("{type=");
printxval(lockfcmds, fl.l_type, "F_???");

126
signal.c
View File

@ -35,6 +35,7 @@
#include "defs.h"
#include <stdint.h>
#include <signal.h>
#include <sys/user.h>
#include <fcntl.h>
@ -1860,15 +1861,19 @@ sys_rt_sigprocmask(tcp)
/* Structure describing the action to be taken when a signal arrives. */
struct new_sigaction
{
union
{
__sighandler_t __sa_handler;
void (*__sa_sigaction) (int, siginfo_t *, void *);
}
__sigaction_handler;
__sighandler_t __sa_handler;
unsigned long sa_flags;
void (*sa_restorer) (void);
unsigned long int sa_mask[2];
/* Kernel treats sa_mask as an array of longs. */
unsigned long sa_mask[NSIG / sizeof(long) ? NSIG / sizeof(long) : 1];
};
/* Same for i386-on-x86_64 and similar cases */
struct new_sigaction32
{
uint32_t __sa_handler;
uint32_t sa_flags;
uint32_t sa_restorer;
uint32_t sa_mask[2 * (NSIG / sizeof(long) ? NSIG / sizeof(long) : 1)];
};
@ -1878,6 +1883,7 @@ sys_rt_sigaction(struct tcb *tcp)
struct new_sigaction sa;
sigset_t sigset;
long addr;
int r;
if (entering(tcp)) {
printsignal(tcp->u_arg[0]);
@ -1885,41 +1891,79 @@ sys_rt_sigaction(struct tcb *tcp)
addr = tcp->u_arg[1];
} else
addr = tcp->u_arg[2];
if (addr == 0)
if (addr == 0) {
tprintf("NULL");
else if (!verbose(tcp))
tprintf("%#lx", addr);
else if (umove(tcp, addr, &sa) < 0)
tprintf("{...}");
else {
if (sa.__sigaction_handler.__sa_handler == SIG_ERR)
tprintf("{SIG_ERR, ");
else if (sa.__sigaction_handler.__sa_handler == SIG_DFL)
tprintf("{SIG_DFL, ");
else if (sa.__sigaction_handler.__sa_handler == SIG_IGN)
tprintf("{SIG_IGN, ");
else
tprintf("{%#lx, ",
(long) sa.__sigaction_handler.__sa_handler);
sigemptyset(&sigset);
#ifdef LINUXSPARC
if (tcp->u_arg[4] <= sizeof(sigset))
memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
#else
if (tcp->u_arg[3] <= sizeof(sigset))
memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
#endif
else
memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
printsigmask(&sigset, 1);
tprintf(", ");
printflags(sigact_flags, sa.sa_flags, "SA_???");
#ifdef SA_RESTORER
if (sa.sa_flags & SA_RESTORER)
tprintf(", %p", sa.sa_restorer);
#endif
tprintf("}");
goto after_sa;
}
if (!verbose(tcp)) {
tprintf("%#lx", addr);
goto after_sa;
}
#if SUPPORTED_PERSONALITIES > 1
if (personality_wordsize[current_personality] != sizeof(sa.sa_flags)
&& personality_wordsize[current_personality] == 4
) {
struct new_sigaction32 sa32;
r = umove(tcp, addr, &sa32);
if (r >= 0) {
memset(&sa, 0, sizeof(sa));
sa.__sa_handler = (void*)(unsigned long)sa32.__sa_handler;
sa.sa_flags = sa32.sa_flags;
sa.sa_restorer = (void*)(unsigned long)sa32.sa_restorer;
/* Kernel treats sa_mask as an array of longs.
* For 32-bit process, "long" is uint32_t, thus, for example,
* 32th bit in sa_mask will end up as bit 0 in sa_mask[1].
* But for (64-bit) kernel, 32th bit in sa_mask is
* 32th bit in 0th (64-bit) long!
* For little-endian, it's the same.
* For big-endian, we swap 32-bit words.
*/
sa.sa_mask[0] = sa32.sa_mask[0] + ((long)(sa32.sa_mask[1]) << 32);
}
} else
#endif
{
r = umove(tcp, addr, &sa);
}
if (r < 0) {
tprintf("{...}");
goto after_sa;
}
if (sa.__sa_handler == SIG_ERR)
tprintf("{SIG_ERR, ");
else if (sa.__sa_handler == SIG_DFL)
tprintf("{SIG_DFL, ");
else if (sa.__sa_handler == SIG_IGN)
tprintf("{SIG_IGN, ");
else
tprintf("{%#lx, ", (long) sa.__sa_handler);
/* Questionable code below.
* Kernel won't handle sys_rt_sigaction
* with wrong sigset size (just returns EINVAL)
* therefore tcp->u_arg[3(4)] _must_ be NSIG / 8 here,
* and we always use smaller memcpy. */
sigemptyset(&sigset);
#ifdef LINUXSPARC
if (tcp->u_arg[4] <= sizeof(sigset))
memcpy(&sigset, &sa.sa_mask, tcp->u_arg[4]);
#else
if (tcp->u_arg[3] <= sizeof(sigset))
memcpy(&sigset, &sa.sa_mask, tcp->u_arg[3]);
#endif
else
memcpy(&sigset, &sa.sa_mask, sizeof(sigset));
printsigmask(&sigset, 1);
tprintf(", ");
printflags(sigact_flags, sa.sa_flags, "SA_???");
#ifdef SA_RESTORER
if (sa.sa_flags & SA_RESTORER)
tprintf(", %p", sa.sa_restorer);
#endif
tprintf("}");
after_sa:
if (entering(tcp))
tprintf(", ");
else
@ -1928,7 +1972,7 @@ sys_rt_sigaction(struct tcb *tcp)
#elif defined(ALPHA)
tprintf(", %lu, %#lx", tcp->u_arg[3], tcp->u_arg[4]);
#else
tprintf(", %lu", addr = tcp->u_arg[3]);
tprintf(", %lu", tcp->u_arg[3]);
#endif
return 0;
}