2003-06-03 Roland McGrath <roland@redhat.com>
Linux/ARM improvements from Russell King <rmk@arm.linux.org.uk>: * defs.h [LINUX] (TCB_WAITEXECVE): Define for [ARM] too. * process.c (struct_user_offsets) [LINUX] [ARM]: Add ARM registers. * signal.c [LINUX] (sys_sigreturn) [ARM]: New case. * syscall.c (get_scno, syscall_fixup) [LINUX] [ARM]: Case rewritten. (get_error) [LINUX] [ARM]: Update. (syscall_enter) [LINUX] [ARM]: New case. * util.c (printcall) [LINUX] [ARM]: New case.
This commit is contained in:
parent
ef38868961
commit
0f87c4972f
2
defs.h
2
defs.h
@ -318,7 +318,7 @@ struct tcb {
|
||||
#define TCB_FOLLOWFORK 00400 /* Process should have forks followed */
|
||||
#define TCB_REPRINT 01000 /* We should reprint this syscall on exit */
|
||||
#ifdef LINUX
|
||||
# if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) || defined(SHMEDIA) || defined(S390) || defined(S390X)
|
||||
# if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) || defined(SHMEDIA) || defined(S390) || defined(S390X) || defined(ARM)
|
||||
# define TCB_WAITEXECVE 02000 /* ignore SIGTRAP after exceve */
|
||||
# endif
|
||||
# define TCB_CLONE_DETACHED 04000 /* CLONE_DETACHED set in creating syscall */
|
||||
|
19
process.c
19
process.c
@ -2626,6 +2626,25 @@ struct xlat struct_user_offsets[] = {
|
||||
{ uoff(regs), "offsetof(struct user, regs)" },
|
||||
{ uoff(fpu), "offsetof(struct user, fpu)" },
|
||||
#endif
|
||||
#ifdef ARM
|
||||
{ uoff(regs.ARM_r0), "r0" },
|
||||
{ uoff(regs.ARM_r1), "r1" },
|
||||
{ uoff(regs.ARM_r2), "r2" },
|
||||
{ uoff(regs.ARM_r3), "r3" },
|
||||
{ uoff(regs.ARM_r4), "r4" },
|
||||
{ uoff(regs.ARM_r5), "r5" },
|
||||
{ uoff(regs.ARM_r6), "r6" },
|
||||
{ uoff(regs.ARM_r7), "r7" },
|
||||
{ uoff(regs.ARM_r8), "r8" },
|
||||
{ uoff(regs.ARM_r9), "r9" },
|
||||
{ uoff(regs.ARM_r10), "r10" },
|
||||
{ uoff(regs.ARM_fp), "fp" },
|
||||
{ uoff(regs.ARM_ip), "ip" },
|
||||
{ uoff(regs.ARM_sp), "sp" },
|
||||
{ uoff(regs.ARM_lr), "lr" },
|
||||
{ uoff(regs.ARM_pc), "pc" },
|
||||
{ uoff(regs.ARM_cpsr), "cpsr" },
|
||||
#endif
|
||||
|
||||
#if !defined(S390) && !defined(S390X) && !defined(MIPS)
|
||||
{ uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
|
||||
|
153
signal.c
153
signal.c
@ -1183,26 +1183,51 @@ int
|
||||
sys_sigreturn(tcp)
|
||||
struct tcb *tcp;
|
||||
{
|
||||
#if defined(S390) || defined(S390X)
|
||||
long usp;
|
||||
struct sigcontext_struct sc;
|
||||
#ifdef ARM
|
||||
struct pt_regs regs;
|
||||
struct sigcontext_struct sc;
|
||||
|
||||
if (entering(tcp)) {
|
||||
tcp->u_arg[0] = 0;
|
||||
if (upeek(tcp->pid,PT_GPR15,&usp)<0)
|
||||
return 0;
|
||||
if (umove(tcp, usp+__SIGNAL_FRAMESIZE, &sc) < 0)
|
||||
return 0;
|
||||
tcp->u_arg[0] = 1;
|
||||
memcpy(&tcp->u_arg[1],&sc.oldmask[0],sizeof(sigset_t));
|
||||
} else {
|
||||
tcp->u_rval = tcp->u_error = 0;
|
||||
if (tcp->u_arg[0] == 0)
|
||||
return 0;
|
||||
tcp->auxstr = sprintsigmask("mask now ",(sigset_t *)&tcp->u_arg[1],0);
|
||||
return RVAL_NONE | RVAL_STR;
|
||||
}
|
||||
return 0;
|
||||
if (entering(tcp)) {
|
||||
tcp->u_arg[0] = 0;
|
||||
|
||||
if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
|
||||
return 0;
|
||||
|
||||
if (umove(tcp, regs.ARM_sp, &sc) < 0)
|
||||
return 0;
|
||||
|
||||
tcp->u_arg[0] = 1;
|
||||
tcp->u_arg[1] = sc.oldmask;
|
||||
} else {
|
||||
sigset_t sigm;
|
||||
long_to_sigset(tcp->u_arg[1], &sigm);
|
||||
tcp->u_rval = tcp->u_error = 0;
|
||||
if (tcp->u_arg[0] == 0)
|
||||
return 0;
|
||||
tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
|
||||
return RVAL_NONE | RVAL_STR;
|
||||
}
|
||||
return 0;
|
||||
#elif defined(S390) || defined(S390X)
|
||||
long usp;
|
||||
struct sigcontext_struct sc;
|
||||
|
||||
if (entering(tcp)) {
|
||||
tcp->u_arg[0] = 0;
|
||||
if (upeek(tcp->pid,PT_GPR15,&usp)<0)
|
||||
return 0;
|
||||
if (umove(tcp, usp+__SIGNAL_FRAMESIZE, &sc) < 0)
|
||||
return 0;
|
||||
tcp->u_arg[0] = 1;
|
||||
memcpy(&tcp->u_arg[1],&sc.oldmask[0],sizeof(sigset_t));
|
||||
} else {
|
||||
tcp->u_rval = tcp->u_error = 0;
|
||||
if (tcp->u_arg[0] == 0)
|
||||
return 0;
|
||||
tcp->auxstr = sprintsigmask("mask now ",(sigset_t *)&tcp->u_arg[1],0);
|
||||
return RVAL_NONE | RVAL_STR;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
#ifdef I386
|
||||
long esp;
|
||||
@ -1256,50 +1281,50 @@ struct tcb *tcp;
|
||||
return 0;
|
||||
#else /* !IA64 */
|
||||
#ifdef POWERPC
|
||||
long esp;
|
||||
struct sigcontext_struct sc;
|
||||
long esp;
|
||||
struct sigcontext_struct sc;
|
||||
|
||||
if (entering(tcp)) {
|
||||
tcp->u_arg[0] = 0;
|
||||
if (upeek(tcp->pid, sizeof(unsigned long)*PT_R1, &esp) < 0)
|
||||
return 0;
|
||||
if (umove(tcp, esp, &sc) < 0)
|
||||
return 0;
|
||||
tcp->u_arg[0] = 1;
|
||||
tcp->u_arg[1] = sc.oldmask;
|
||||
}
|
||||
else {
|
||||
sigset_t sigm;
|
||||
long_to_sigset(tcp->u_arg[1], &sigm);
|
||||
tcp->u_rval = tcp->u_error = 0;
|
||||
if (tcp->u_arg[0] == 0)
|
||||
return 0;
|
||||
tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
|
||||
return RVAL_NONE | RVAL_STR;
|
||||
}
|
||||
return 0;
|
||||
if (entering(tcp)) {
|
||||
tcp->u_arg[0] = 0;
|
||||
if (upeek(tcp->pid, sizeof(unsigned long)*PT_R1, &esp) < 0)
|
||||
return 0;
|
||||
if (umove(tcp, esp, &sc) < 0)
|
||||
return 0;
|
||||
tcp->u_arg[0] = 1;
|
||||
tcp->u_arg[1] = sc.oldmask;
|
||||
}
|
||||
else {
|
||||
sigset_t sigm;
|
||||
long_to_sigset(tcp->u_arg[1], &sigm);
|
||||
tcp->u_rval = tcp->u_error = 0;
|
||||
if (tcp->u_arg[0] == 0)
|
||||
return 0;
|
||||
tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
|
||||
return RVAL_NONE | RVAL_STR;
|
||||
}
|
||||
return 0;
|
||||
#else /* !POWERPC */
|
||||
#ifdef M68K
|
||||
long usp;
|
||||
struct sigcontext sc;
|
||||
|
||||
if (entering(tcp)) {
|
||||
tcp->u_arg[0] = 0;
|
||||
if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
|
||||
tcp->u_arg[0] = 0;
|
||||
if (upeek(tcp->pid, 4*PT_USP, &usp) < 0)
|
||||
return 0;
|
||||
if (umove(tcp, usp, &sc) < 0)
|
||||
if (umove(tcp, usp, &sc) < 0)
|
||||
return 0;
|
||||
tcp->u_arg[0] = 1;
|
||||
tcp->u_arg[1] = sc.sc_mask;
|
||||
tcp->u_arg[0] = 1;
|
||||
tcp->u_arg[1] = sc.sc_mask;
|
||||
}
|
||||
else {
|
||||
sigset_t sigm;
|
||||
long_to_sigset(tcp->u_arg[1], &sigm);
|
||||
tcp->u_rval = tcp->u_error = 0;
|
||||
if (tcp->u_arg[0] == 0)
|
||||
sigset_t sigm;
|
||||
long_to_sigset(tcp->u_arg[1], &sigm);
|
||||
tcp->u_rval = tcp->u_error = 0;
|
||||
if (tcp->u_arg[0] == 0)
|
||||
return 0;
|
||||
tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
|
||||
return RVAL_NONE | RVAL_STR;
|
||||
tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
|
||||
return RVAL_NONE | RVAL_STR;
|
||||
}
|
||||
return 0;
|
||||
#else /* !M68K */
|
||||
@ -1308,22 +1333,22 @@ struct tcb *tcp;
|
||||
struct sigcontext_struct sc;
|
||||
|
||||
if (entering(tcp)) {
|
||||
tcp->u_arg[0] = 0;
|
||||
if (upeek(tcp->pid, REG_FP, &fp) < 0)
|
||||
tcp->u_arg[0] = 0;
|
||||
if (upeek(tcp->pid, REG_FP, &fp) < 0)
|
||||
return 0;
|
||||
if (umove(tcp, fp, &sc) < 0)
|
||||
if (umove(tcp, fp, &sc) < 0)
|
||||
return 0;
|
||||
tcp->u_arg[0] = 1;
|
||||
tcp->u_arg[1] = sc.sc_mask;
|
||||
tcp->u_arg[0] = 1;
|
||||
tcp->u_arg[1] = sc.sc_mask;
|
||||
}
|
||||
else {
|
||||
sigset_t sigm;
|
||||
long_to_sigset(tcp->u_arg[1], &sigm);
|
||||
tcp->u_rval = tcp->u_error = 0;
|
||||
if (tcp->u_arg[0] == 0)
|
||||
sigset_t sigm;
|
||||
long_to_sigset(tcp->u_arg[1], &sigm);
|
||||
tcp->u_rval = tcp->u_error = 0;
|
||||
if (tcp->u_arg[0] == 0)
|
||||
return 0;
|
||||
tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
|
||||
return RVAL_NONE | RVAL_STR;
|
||||
tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
|
||||
return RVAL_NONE | RVAL_STR;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
@ -1333,8 +1358,8 @@ struct tcb *tcp;
|
||||
m_siginfo_t si;
|
||||
|
||||
if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) {
|
||||
perror("sigreturn: PTRACE_GETREGS ");
|
||||
return 0;
|
||||
perror("sigreturn: PTRACE_GETREGS ");
|
||||
return 0;
|
||||
}
|
||||
if(entering(tcp)) {
|
||||
tcp->u_arg[0] = 0;
|
||||
|
89
syscall.c
89
syscall.c
@ -695,7 +695,7 @@ struct tcb *tcp;
|
||||
#elif defined (M68K)
|
||||
static int d0;
|
||||
#elif defined (ARM)
|
||||
static int r0;
|
||||
static struct pt_regs regs;
|
||||
#elif defined (ALPHA)
|
||||
static long r0;
|
||||
static long a3;
|
||||
@ -714,7 +714,7 @@ struct tcb *tcp;
|
||||
#elif defined(SH)
|
||||
static long r0;
|
||||
#elif defined(SHMEDIA)
|
||||
static long r9;
|
||||
static long r9;
|
||||
#elif defined(X86_64)
|
||||
static long rax;
|
||||
#endif
|
||||
@ -939,11 +939,59 @@ struct tcb *tcp;
|
||||
return -1;
|
||||
}
|
||||
#elif defined (ARM)
|
||||
{
|
||||
long pc;
|
||||
upeek(pid, 4*15, &pc);
|
||||
umoven(tcp, pc-4, 4, (char *)&scno);
|
||||
scno &= 0x000fffff;
|
||||
/*
|
||||
* Read complete register set in one go.
|
||||
*/
|
||||
if (ptrace(PTRACE_GETREGS, pid, NULL, (void *)®s) == -1)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* We only need to grab the syscall number on syscall entry.
|
||||
*/
|
||||
if (regs.ARM_ip == 0) {
|
||||
/*
|
||||
* Note: we only deal with only 32-bit CPUs here.
|
||||
*/
|
||||
if (regs.ARM_cpsr & 0x20) {
|
||||
/*
|
||||
* Get the Thumb-mode system call number
|
||||
*/
|
||||
scno = regs.ARM_r7;
|
||||
} else {
|
||||
/*
|
||||
* Get the ARM-mode system call number
|
||||
*/
|
||||
errno = 0;
|
||||
scno = ptrace(PTRACE_PEEKTEXT, pid, (void *)(regs.ARM_pc - 4), NULL);
|
||||
if (errno)
|
||||
return -1;
|
||||
|
||||
if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
|
||||
tcp->flags &= ~TCB_WAITEXECVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((scno & 0x0ff00000) != 0x0f900000) {
|
||||
fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
|
||||
scno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixup the syscall number
|
||||
*/
|
||||
scno &= 0x000fffff;
|
||||
}
|
||||
|
||||
if (tcp->flags & TCB_INSYSCALL) {
|
||||
fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
|
||||
tcp->flags &= ~TCB_INSYSCALL;
|
||||
}
|
||||
} else {
|
||||
if (!(tcp->flags & TCB_INSYSCALL)) {
|
||||
fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
|
||||
tcp->flags |= TCB_INSYSCALL;
|
||||
}
|
||||
}
|
||||
#elif defined (M68K)
|
||||
if (upeek(pid, 4*PT_ORIG_D0, &scno) < 0)
|
||||
@ -1272,13 +1320,9 @@ struct tcb *tcp;
|
||||
return 0;
|
||||
}
|
||||
#elif defined (ARM)
|
||||
if (upeek(pid, 4*0, (long *)&r0) < 0)
|
||||
return -1;
|
||||
if ( 0 && r0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
|
||||
if (debug)
|
||||
fprintf(stderr, "stray syscall exit: d0 = %ld\n", r0);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Nothing required
|
||||
*/
|
||||
#elif defined (HPPA)
|
||||
if (upeek(pid, PT_GR28, &r28) < 0)
|
||||
return -1;
|
||||
@ -1386,12 +1430,12 @@ struct tcb *tcp;
|
||||
}
|
||||
#else /* !M68K */
|
||||
#ifdef ARM
|
||||
if (r0 && (unsigned) -r0 < nerrnos) {
|
||||
if (regs.ARM_r0 && (unsigned) -regs.ARM_r0 < nerrnos) {
|
||||
tcp->u_rval = -1;
|
||||
u_error = -r0;
|
||||
u_error = -regs.ARM_r0;
|
||||
}
|
||||
else {
|
||||
tcp->u_rval = r0;
|
||||
tcp->u_rval = regs.ARM_r0;
|
||||
u_error = 0;
|
||||
}
|
||||
#else /* !ARM */
|
||||
@ -1864,6 +1908,17 @@ struct tcb *tcp;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#elif defined(ARM)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
|
||||
tcp->u_nargs = sysent[tcp->scno].nargs;
|
||||
else
|
||||
tcp->u_nargs = MAX_ARGS;
|
||||
for (i = 0; i < tcp->u_nargs; i++)
|
||||
tcp->u_arg[i] = regs.uregs[i];
|
||||
}
|
||||
#elif defined(SH)
|
||||
{
|
||||
int i;
|
||||
|
Loading…
x
Reference in New Issue
Block a user