2003-01-20 Roland McGrath <roland@redhat.com>
* defs.h [LINUX] [S390 || S390X] (TCB_WAITEXECVE): Define it. * syscall.c (get_scno, syscall_fixup) [LINUX] [S390 || S390X]: Handle TCB_WAITEXECVE state with special kludges.
This commit is contained in:
parent
08eee593ea
commit
96dc5148ff
2
defs.h
2
defs.h
@ -301,7 +301,7 @@ struct tcb {
|
|||||||
#define TCB_FOLLOWFORK 00400 /* Process should have forks followed */
|
#define TCB_FOLLOWFORK 00400 /* Process should have forks followed */
|
||||||
#define TCB_REPRINT 01000 /* We should reprint this syscall on exit */
|
#define TCB_REPRINT 01000 /* We should reprint this syscall on exit */
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
# if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH)
|
# if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) || defined(S390) || defined(S390X)
|
||||||
# define TCB_WAITEXECVE 02000 /* ignore SIGTRAP after exceve */
|
# define TCB_WAITEXECVE 02000 /* ignore SIGTRAP after exceve */
|
||||||
# endif
|
# endif
|
||||||
# define TCB_CLONE_DETACHED 04000 /* CLONE_DETACHED set in creating syscall */
|
# define TCB_CLONE_DETACHED 04000 /* CLONE_DETACHED set in creating syscall */
|
||||||
|
35
syscall.c
35
syscall.c
@ -730,12 +730,31 @@ struct tcb *tcp;
|
|||||||
#if defined(S390) || defined(S390X)
|
#if defined(S390) || defined(S390X)
|
||||||
if (upeek(pid, PT_GPR2, &syscall_mode) < 0)
|
if (upeek(pid, PT_GPR2, &syscall_mode) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (syscall_mode != -ENOSYS){
|
if (syscall_mode != -ENOSYS) {
|
||||||
/*
|
/*
|
||||||
* Since kernel version 2.5.44 the scno gets passed in gpr2.
|
* Since kernel version 2.5.44 the scno gets passed in gpr2.
|
||||||
*/
|
*/
|
||||||
scno = syscall_mode;
|
scno = syscall_mode;
|
||||||
}
|
}
|
||||||
|
if (tcp->flags & TCB_WAITEXECVE) {
|
||||||
|
/*
|
||||||
|
* When the execve system call completes successfully, the
|
||||||
|
* new process still has -ENOSYS (old style) or __NR_execve
|
||||||
|
* (new style) in gpr2. We cannot recover the scno again
|
||||||
|
* by disassembly, because the image that executed the
|
||||||
|
* syscall is gone now. Fortunately, we don't want it. We
|
||||||
|
* leave the flag set so that syscall_fixup can fake the
|
||||||
|
* result.
|
||||||
|
*/
|
||||||
|
if (tcp->flags & TCB_INSYSCALL)
|
||||||
|
return 1;
|
||||||
|
/*
|
||||||
|
* This is the SIGTRAP after execve. We cannot try to read
|
||||||
|
* the system call here either.
|
||||||
|
*/
|
||||||
|
tcp->flags &= ~TCB_WAITEXECVE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
/*
|
/*
|
||||||
* Old style of "passing" the scno via the SVC instruction.
|
* Old style of "passing" the scno via the SVC instruction.
|
||||||
@ -750,9 +769,12 @@ struct tcb *tcp;
|
|||||||
|
|
||||||
if (upeek(pid, PT_PSWADDR, &pc) < 0)
|
if (upeek(pid, PT_PSWADDR, &pc) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
errno = 0;
|
||||||
opcode = ptrace(PTRACE_PEEKTEXT, pid, (char *)(pc-sizeof(long)), 0);
|
opcode = ptrace(PTRACE_PEEKTEXT, pid, (char *)(pc-sizeof(long)), 0);
|
||||||
if (errno)
|
if (errno) {
|
||||||
|
perror("peektext(pc-oneword)");
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have to check if the SVC got executed directly or via an
|
* We have to check if the SVC got executed directly or via an
|
||||||
@ -1202,6 +1224,15 @@ struct tcb *tcp;
|
|||||||
fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
|
fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
|
||||||
|
== (TCB_INSYSCALL|TCB_WAITEXECVE))
|
||||||
|
&& (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
|
||||||
|
/*
|
||||||
|
* Fake a return value of zero. We leave the TCB_WAITEXECVE
|
||||||
|
* flag set for the post-execve SIGTRAP to see and reset.
|
||||||
|
*/
|
||||||
|
gpr2 = 0;
|
||||||
|
}
|
||||||
#elif defined (POWERPC)
|
#elif defined (POWERPC)
|
||||||
# define SO_MASK 0x10000000
|
# define SO_MASK 0x10000000
|
||||||
if (upeek(pid, sizeof(unsigned long)*PT_CCR, &flags) < 0)
|
if (upeek(pid, sizeof(unsigned long)*PT_CCR, &flags) < 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user