summaryrefslogtreecommitdiff
path: root/process.c
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2016-04-01 00:28:33 +0000
committerDmitry V. Levin <ldv@altlinux.org>2016-04-01 00:28:33 +0000
commitccdc82a57d276ee9d4313c3c81662115ee40207c (patch)
tree39a8139f06484ca1c72eaf3b657eb803dc699360 /process.c
parent1f3482bedad505a41caf1d61b3a4e7e09a2f4330 (diff)
downloadstrace-ccdc82a57d276ee9d4313c3c81662115ee40207c.tar.gz
Cleanup parser of ptrace syscall
* process.c (print_user_offset_addr): New function for printing offset address in the tracee's USER area. (SYS_FUNC(ptrace)): Assign syscall arguments to local variables with appropriate types. Print pid argument as int. Use switch statement in the code that handles address argument. Use print_user_offset_addr to print address in PTRACE_PEEKUSER and PTRACE_POKEUSER requests.
Diffstat (limited to 'process.c')
-rw-r--r--process.c94
1 files changed, 55 insertions, 39 deletions
diff --git a/process.c b/process.c
index 862918426..1526dd64a 100644
--- a/process.c
+++ b/process.c
@@ -55,40 +55,58 @@ static const struct xlat struct_user_offsets[] = {
XLAT_END
};
-SYS_FUNC(ptrace)
+static void
+print_user_offset_addr(const unsigned long addr)
{
const struct xlat *x;
- unsigned long addr;
+
+ for (x = struct_user_offsets; x->str; ++x) {
+ if (x->val >= addr)
+ break;
+ }
+
+ if (!x->str) {
+ printaddr(addr);
+ } else if (x->val > addr) {
+ if (x == struct_user_offsets) {
+ printaddr(addr);
+ } else {
+ --x;
+ tprintf("%s + %lu",
+ x->str, addr - (unsigned long) x->val);
+ }
+ } else {
+ tprints(x->str);
+ }
+}
+
+SYS_FUNC(ptrace)
+{
+ const long request = tcp->u_arg[0];
+ const int pid = tcp->u_arg[1];
+ const unsigned long addr = tcp->u_arg[2];
+ const unsigned long data = tcp->u_arg[3];
if (entering(tcp)) {
- printxval(ptrace_cmds, tcp->u_arg[0], "PTRACE_???");
- tprintf(", %lu, ", tcp->u_arg[1]);
+ printxval(ptrace_cmds, request, "PTRACE_???");
+ tprintf(", %d, ", pid);
- addr = tcp->u_arg[2];
- if (tcp->u_arg[0] == PTRACE_PEEKUSER
- || tcp->u_arg[0] == PTRACE_POKEUSER
- ) {
- for (x = struct_user_offsets; x->str; x++) {
- if (x->val >= addr)
- break;
- }
- if (!x->str)
- printaddr(addr);
- else if (x->val > addr && x != struct_user_offsets) {
- x--;
- tprintf("%s + %ld", x->str, addr - x->val);
- }
- else
- tprints(x->str);
- } else
- if (tcp->u_arg[0] == PTRACE_GETREGSET
- || tcp->u_arg[0] == PTRACE_SETREGSET)
- printxval(nt_descriptor_types, tcp->u_arg[2], "NT_???");
- else
+ switch (request) {
+ case PTRACE_PEEKUSER:
+ case PTRACE_POKEUSER:
+ print_user_offset_addr(addr);
+ break;
+ case PTRACE_GETREGSET:
+ case PTRACE_SETREGSET:
+ printxval(nt_descriptor_types, addr, "NT_???");
+ break;
+ default:
printaddr(addr);
+ }
+
tprints(", ");
- switch (tcp->u_arg[0]) {
+ switch (request) {
#ifndef IA64
case PTRACE_PEEKDATA:
case PTRACE_PEEKTEXT:
@@ -99,43 +117,41 @@ SYS_FUNC(ptrace)
case PTRACE_SINGLESTEP:
case PTRACE_SYSCALL:
case PTRACE_DETACH:
- printsignal(tcp->u_arg[3]);
+ printsignal(data);
break;
case PTRACE_SETOPTIONS:
- printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
+ printflags(ptrace_setoptions_flags, data, "PTRACE_O_???");
break;
- case PTRACE_SETSIGINFO: {
- printsiginfo_at(tcp, tcp->u_arg[3]);
+ case PTRACE_SETSIGINFO:
+ printsiginfo_at(tcp, data);
break;
- }
case PTRACE_SETREGSET:
- tprint_iov(tcp, /*len:*/ 1, tcp->u_arg[3], /*as string:*/ 0);
+ tprint_iov(tcp, /*len:*/ 1, data, /*as string:*/ 0);
break;
case PTRACE_GETSIGINFO:
case PTRACE_GETREGSET:
/* Don't print anything, do it at syscall return. */
break;
default:
- printaddr(tcp->u_arg[3]);
+ printaddr(data);
break;
}
} else {
- switch (tcp->u_arg[0]) {
+ switch (request) {
case PTRACE_PEEKDATA:
case PTRACE_PEEKTEXT:
case PTRACE_PEEKUSER:
#ifdef IA64
return RVAL_HEX;
#else
- printnum_ptr(tcp, tcp->u_arg[3]);
+ printnum_ptr(tcp, data);
break;
#endif
- case PTRACE_GETSIGINFO: {
- printsiginfo_at(tcp, tcp->u_arg[3]);
+ case PTRACE_GETSIGINFO:
+ printsiginfo_at(tcp, data);
break;
- }
case PTRACE_GETREGSET:
- tprint_iov(tcp, /*len:*/ 1, tcp->u_arg[3], /*as string:*/ 0);
+ tprint_iov(tcp, /*len:*/ 1, data, /*as string:*/ 0);
break;
}
}