Message type for PM_PTRACE

Change-Id: I19bbd5faa5c7511cda0239109b2ac55869c47b96
This commit is contained in:
Lionel Sambuc 2014-05-13 10:07:12 +02:00
parent a5ed845b20
commit 345b3b5114
5 changed files with 56 additions and 43 deletions

View file

@ -64,12 +64,6 @@
/* Field names for the exit(2) call. */ /* Field names for the exit(2) call. */
#define PM_EXIT_STATUS m1_i1 /* int */ #define PM_EXIT_STATUS m1_i1 /* int */
/* Field names for the ptrace(2) call. */
#define PM_PTRACE_PID m2_i1 /* pid_t */
#define PM_PTRACE_REQ m2_i2 /* int */
#define PM_PTRACE_ADDR m2_l1 /* long */
#define PM_PTRACE_DATA m2_l2 /* long */
/* Field names for the sysuname(2) call. */ /* Field names for the sysuname(2) call. */
#define PM_SYSUNAME_REQ m1_i1 /* int */ #define PM_SYSUNAME_REQ m1_i1 /* int */
#define PM_SYSUNAME_FIELD m1_i2 /* int */ #define PM_SYSUNAME_FIELD m1_i2 /* int */

View file

@ -154,6 +154,23 @@ typedef struct {
} mess_lc_pm_itimer; } mess_lc_pm_itimer;
_ASSERT_MSG_SIZE(mess_lc_pm_itimer); _ASSERT_MSG_SIZE(mess_lc_pm_itimer);
typedef struct {
pid_t pid;
int req;
vir_bytes addr;
long data;
uint8_t padding[40];
} mess_lc_pm_ptrace;
_ASSERT_MSG_SIZE(mess_lc_pm_ptrace);
typedef struct {
long data;
uint8_t padding[52];
} mess_pm_lc_ptrace;
_ASSERT_MSG_SIZE(mess_pm_lc_ptrace);
typedef struct { typedef struct {
time_t sec; time_t sec;
@ -932,6 +949,7 @@ typedef struct {
mess_fs_vfs_readwrite m_fs_vfs_readwrite; mess_fs_vfs_readwrite m_fs_vfs_readwrite;
mess_lc_pm_itimer m_lc_pm_itimer; mess_lc_pm_itimer m_lc_pm_itimer;
mess_lc_pm_ptrace m_lc_pm_ptrace;
mess_lc_pm_time m_lc_pm_time; mess_lc_pm_time m_lc_pm_time;
mess_lc_pm_waitpid m_lc_pm_waitpid; mess_lc_pm_waitpid m_lc_pm_waitpid;
@ -967,6 +985,7 @@ typedef struct {
mess_lsys_vfs_copyfd m_lsys_vfs_copyfd; mess_lsys_vfs_copyfd m_lsys_vfs_copyfd;
mess_lsys_vfs_mapdriver m_lsys_vfs_mapdriver; mess_lsys_vfs_mapdriver m_lsys_vfs_mapdriver;
mess_pm_lc_ptrace m_pm_lc_ptrace;
mess_pm_lc_time m_pm_lc_time; mess_pm_lc_time m_pm_lc_time;
mess_pm_lc_waitpid m_pm_lc_waitpid; mess_pm_lc_waitpid m_pm_lc_waitpid;

View file

@ -10,16 +10,16 @@ int ptrace(int req, pid_t pid, void *addr, int data)
message m; message m;
memset(&m, 0, sizeof(m)); memset(&m, 0, sizeof(m));
m.PM_PTRACE_PID = pid; m.m_lc_pm_ptrace.pid = pid;
m.PM_PTRACE_REQ = req; m.m_lc_pm_ptrace.req = req;
m.PM_PTRACE_ADDR = addr; m.m_lc_pm_ptrace.addr = addr;
m.PM_PTRACE_DATA = data; m.m_lc_pm_ptrace.data = data;
if (_syscall(PM_PROC_NR, PM_PTRACE, &m) < 0) return(-1); if (_syscall(PM_PROC_NR, PM_PTRACE, &m) < 0) return(-1);
/* There was no error, but -1 is a legal return value. Clear errno if /* There was no error, but -1 is a legal return value. Clear errno if
* necessary to distinguish this case. _syscall has set errno to nonzero * necessary to distinguish this case. _syscall has set errno to nonzero
* for the error case. * for the error case.
*/ */
if (m.PM_PTRACE_DATA == -1) errno = 0; if (m.m_pm_lc_ptrace.data == -1) errno = 0;
return(m.PM_PTRACE_DATA); return(m.m_pm_lc_ptrace.data);
} }

View file

@ -437,7 +437,7 @@ int dump_core; /* flag indicating whether to dump core */
if (rmp->mp_flags & TRACE_EXIT) if (rmp->mp_flags & TRACE_EXIT)
{ {
/* Wake up the tracer, completing the ptrace(T_EXIT) call */ /* Wake up the tracer, completing the ptrace(T_EXIT) call */
mproc[rmp->mp_tracer].mp_reply.PM_PTRACE_DATA = 0; mproc[rmp->mp_tracer].mp_reply.m_pm_lc_ptrace.data = 0;
reply(rmp->mp_tracer, OK); reply(rmp->mp_tracer, OK);
} }

View file

@ -44,7 +44,7 @@ int do_trace()
struct ptrace_range pr; struct ptrace_range pr;
int i, r, req; int i, r, req;
req = m_in.PM_PTRACE_REQ; req = m_in.m_lc_pm_ptrace.req;
/* The T_OK call is made by the child fork of the debugger before it execs /* The T_OK call is made by the child fork of the debugger before it execs
* the process to be traced. The T_ATTACH call is made by the debugger itself * the process to be traced. The T_ATTACH call is made by the debugger itself
@ -55,11 +55,11 @@ int do_trace()
if (mp->mp_tracer != NO_TRACER) return(EBUSY); if (mp->mp_tracer != NO_TRACER) return(EBUSY);
mp->mp_tracer = mp->mp_parent; mp->mp_tracer = mp->mp_parent;
mp->mp_reply.PM_PTRACE_DATA = 0; mp->mp_reply.m_pm_lc_ptrace.data = 0;
return(OK); return(OK);
case T_ATTACH: /* attach to an existing process */ case T_ATTACH: /* attach to an existing process */
if ((child = find_proc(m_in.PM_PTRACE_PID)) == NULL) return(ESRCH); if ((child = find_proc(m_in.m_lc_pm_ptrace.pid)) == NULL) return(ESRCH);
if (child->mp_flags & EXITING) return(ESRCH); if (child->mp_flags & EXITING) return(ESRCH);
/* For non-root processes, user and group ID must match. */ /* For non-root processes, user and group ID must match. */
@ -88,7 +88,7 @@ int do_trace()
sig_proc(child, SIGSTOP, TRUE /*trace*/, FALSE /* ksig */); sig_proc(child, SIGSTOP, TRUE /*trace*/, FALSE /* ksig */);
mp->mp_reply.PM_PTRACE_DATA = 0; mp->mp_reply.m_pm_lc_ptrace.data = 0;
return(OK); return(OK);
case T_STOP: /* stop the process */ case T_STOP: /* stop the process */
@ -99,19 +99,19 @@ int do_trace()
case T_READB_INS: /* special hack for reading text segments */ case T_READB_INS: /* special hack for reading text segments */
if (mp->mp_effuid != SUPER_USER) return(EPERM); if (mp->mp_effuid != SUPER_USER) return(EPERM);
if ((child = find_proc(m_in.PM_PTRACE_PID)) == NULL) return(ESRCH); if ((child = find_proc(m_in.m_lc_pm_ptrace.pid)) == NULL) return(ESRCH);
if (child->mp_flags & EXITING) return(ESRCH); if (child->mp_flags & EXITING) return(ESRCH);
r = sys_trace(req, child->mp_endpoint, m_in.PM_PTRACE_ADDR, r = sys_trace(req, child->mp_endpoint, m_in.m_lc_pm_ptrace.addr,
&m_in.PM_PTRACE_DATA); &m_in.m_lc_pm_ptrace.data);
if (r != OK) return(r); if (r != OK) return(r);
mp->mp_reply.PM_PTRACE_DATA = m_in.PM_PTRACE_DATA; mp->mp_reply.m_pm_lc_ptrace.data = m_in.m_lc_pm_ptrace.data;
return(OK); return(OK);
case T_WRITEB_INS: /* special hack for patching text segments */ case T_WRITEB_INS: /* special hack for patching text segments */
if (mp->mp_effuid != SUPER_USER) return(EPERM); if (mp->mp_effuid != SUPER_USER) return(EPERM);
if ((child = find_proc(m_in.PM_PTRACE_PID)) == NULL) return(ESRCH); if ((child = find_proc(m_in.m_lc_pm_ptrace.pid)) == NULL) return(ESRCH);
if (child->mp_flags & EXITING) return(ESRCH); if (child->mp_flags & EXITING) return(ESRCH);
#if 0 #if 0
@ -125,18 +125,18 @@ int do_trace()
child->mp_ctime = 0; child->mp_ctime = 0;
#endif #endif
r = sys_trace(req, child->mp_endpoint, m_in.PM_PTRACE_ADDR, r = sys_trace(req, child->mp_endpoint, m_in.m_lc_pm_ptrace.addr,
&m_in.PM_PTRACE_DATA); &m_in.m_lc_pm_ptrace.data);
if (r != OK) return(r); if (r != OK) return(r);
mp->mp_reply.PM_PTRACE_DATA = m_in.PM_PTRACE_DATA; mp->mp_reply.m_pm_lc_ptrace.data = m_in.m_lc_pm_ptrace.data;
return(OK); return(OK);
} }
/* All the other calls are made by the tracing process to control execution /* All the other calls are made by the tracing process to control execution
* of the child. For all these calls, the child must be stopped. * of the child. For all these calls, the child must be stopped.
*/ */
if ((child = find_proc(m_in.PM_PTRACE_PID)) == NULL) return(ESRCH); if ((child = find_proc(m_in.m_lc_pm_ptrace.pid)) == NULL) return(ESRCH);
if (child->mp_flags & EXITING) return(ESRCH); if (child->mp_flags & EXITING) return(ESRCH);
if (child->mp_tracer != who_p) return(ESRCH); if (child->mp_tracer != who_p) return(ESRCH);
if (!(child->mp_flags & TRACE_STOPPED)) return(EBUSY); if (!(child->mp_flags & TRACE_STOPPED)) return(EBUSY);
@ -147,9 +147,9 @@ int do_trace()
/* Defer the exit if the traced process has an VFS call pending. */ /* Defer the exit if the traced process has an VFS call pending. */
if (child->mp_flags & VFS_CALL) if (child->mp_flags & VFS_CALL)
child->mp_exitstatus = (int) m_in.PM_PTRACE_DATA; /* save it */ child->mp_exitstatus = m_in.m_lc_pm_ptrace.data; /* save it */
else else
exit_proc(child, (int) m_in.PM_PTRACE_DATA, exit_proc(child, m_in.m_lc_pm_ptrace.data,
FALSE /*dump_core*/); FALSE /*dump_core*/);
/* Do not reply to the caller until VFS has processed the exit /* Do not reply to the caller until VFS has processed the exit
@ -158,15 +158,15 @@ int do_trace()
return(SUSPEND); return(SUSPEND);
case T_SETOPT: /* set trace options */ case T_SETOPT: /* set trace options */
child->mp_trace_flags = m_in.PM_PTRACE_DATA; child->mp_trace_flags = m_in.m_lc_pm_ptrace.data;
mp->mp_reply.PM_PTRACE_DATA = 0; mp->mp_reply.m_pm_lc_ptrace.data = 0;
return(OK); return(OK);
case T_GETRANGE: case T_GETRANGE:
case T_SETRANGE: /* get/set range of values */ case T_SETRANGE: /* get/set range of values */
r = sys_datacopy(who_e, (vir_bytes) m_in.PM_PTRACE_ADDR, r = sys_datacopy(who_e, m_in.m_lc_pm_ptrace.addr, SELF, (vir_bytes)&pr,
SELF, (vir_bytes) &pr, (phys_bytes) sizeof(pr)); (phys_bytes)sizeof(pr));
if (r != OK) return(r); if (r != OK) return(r);
if (pr.pr_space != TS_INS && pr.pr_space != TS_DATA) return(EINVAL); if (pr.pr_space != TS_INS && pr.pr_space != TS_DATA) return(EINVAL);
@ -183,11 +183,11 @@ int do_trace()
if (r != OK) return(r); if (r != OK) return(r);
mp->mp_reply.PM_PTRACE_DATA = 0; mp->mp_reply.m_pm_lc_ptrace.data = 0;
return(OK); return(OK);
case T_DETACH: /* detach from traced process */ case T_DETACH: /* detach from traced process */
if (m_in.PM_PTRACE_DATA < 0 || m_in.PM_PTRACE_DATA >= _NSIG) if (m_in.m_lc_pm_ptrace.data < 0 || m_in.m_lc_pm_ptrace.data >= _NSIG)
return(EINVAL); return(EINVAL);
child->mp_tracer = NO_TRACER; child->mp_tracer = NO_TRACER;
@ -200,8 +200,8 @@ int do_trace()
} }
} }
if (m_in.PM_PTRACE_DATA > 0) { /* issue signal */ if (m_in.m_lc_pm_ptrace.data > 0) { /* issue signal */
sig_proc(child, (int) m_in.PM_PTRACE_DATA, TRUE /*trace*/, sig_proc(child, m_in.m_lc_pm_ptrace.data, TRUE /*trace*/,
FALSE /* ksig */); FALSE /* ksig */);
} }
@ -216,11 +216,11 @@ int do_trace()
case T_RESUME: case T_RESUME:
case T_STEP: case T_STEP:
case T_SYSCALL: /* resume execution */ case T_SYSCALL: /* resume execution */
if (m_in.PM_PTRACE_DATA < 0 || m_in.PM_PTRACE_DATA >= _NSIG) if (m_in.m_lc_pm_ptrace.data < 0 || m_in.m_lc_pm_ptrace.data >= _NSIG)
return(EINVAL); return(EINVAL);
if (m_in.PM_PTRACE_DATA > 0) { /* issue signal */ if (m_in.m_lc_pm_ptrace.data > 0) { /* issue signal */
sig_proc(child, (int) m_in.PM_PTRACE_DATA, FALSE /*trace*/, sig_proc(child, m_in.m_lc_pm_ptrace.data, FALSE /*trace*/,
FALSE /* ksig */); FALSE /* ksig */);
} }
@ -229,7 +229,7 @@ int do_trace()
*/ */
for (i = 1; i < _NSIG; i++) { for (i = 1; i < _NSIG; i++) {
if (sigismember(&child->mp_sigtrace, i)) { if (sigismember(&child->mp_sigtrace, i)) {
mp->mp_reply.PM_PTRACE_DATA = 0; mp->mp_reply.m_pm_lc_ptrace.data = 0;
return(OK); return(OK);
} }
} }
@ -240,11 +240,11 @@ int do_trace()
break; break;
} }
r = sys_trace(req, child->mp_endpoint, m_in.PM_PTRACE_ADDR, r = sys_trace(req, child->mp_endpoint, m_in.m_lc_pm_ptrace.addr,
&m_in.PM_PTRACE_DATA); &m_in.m_lc_pm_ptrace.data);
if (r != OK) return(r); if (r != OK) return(r);
mp->mp_reply.PM_PTRACE_DATA = m_in.PM_PTRACE_DATA; mp->mp_reply.m_pm_lc_ptrace.data = m_in.m_lc_pm_ptrace.data;
return(OK); return(OK);
} }