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. */
#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. */
#define PM_SYSUNAME_REQ m1_i1 /* int */
#define PM_SYSUNAME_FIELD m1_i2 /* int */

View file

@ -154,6 +154,23 @@ typedef struct {
} 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 {
time_t sec;
@ -932,6 +949,7 @@ typedef struct {
mess_fs_vfs_readwrite m_fs_vfs_readwrite;
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_waitpid m_lc_pm_waitpid;
@ -967,6 +985,7 @@ typedef struct {
mess_lsys_vfs_copyfd m_lsys_vfs_copyfd;
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_waitpid m_pm_lc_waitpid;

View file

@ -10,16 +10,16 @@ int ptrace(int req, pid_t pid, void *addr, int data)
message m;
memset(&m, 0, sizeof(m));
m.PM_PTRACE_PID = pid;
m.PM_PTRACE_REQ = req;
m.PM_PTRACE_ADDR = addr;
m.PM_PTRACE_DATA = data;
m.m_lc_pm_ptrace.pid = pid;
m.m_lc_pm_ptrace.req = req;
m.m_lc_pm_ptrace.addr = addr;
m.m_lc_pm_ptrace.data = data;
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
* necessary to distinguish this case. _syscall has set errno to nonzero
* for the error case.
*/
if (m.PM_PTRACE_DATA == -1) errno = 0;
return(m.PM_PTRACE_DATA);
if (m.m_pm_lc_ptrace.data == -1) errno = 0;
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)
{
/* 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);
}

View file

@ -44,7 +44,7 @@ int do_trace()
struct ptrace_range pr;
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 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);
mp->mp_tracer = mp->mp_parent;
mp->mp_reply.PM_PTRACE_DATA = 0;
mp->mp_reply.m_pm_lc_ptrace.data = 0;
return(OK);
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);
/* 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 */);
mp->mp_reply.PM_PTRACE_DATA = 0;
mp->mp_reply.m_pm_lc_ptrace.data = 0;
return(OK);
case T_STOP: /* stop the process */
@ -99,19 +99,19 @@ int do_trace()
case T_READB_INS: /* special hack for reading text segments */
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);
r = sys_trace(req, child->mp_endpoint, m_in.PM_PTRACE_ADDR,
&m_in.PM_PTRACE_DATA);
r = sys_trace(req, child->mp_endpoint, m_in.m_lc_pm_ptrace.addr,
&m_in.m_lc_pm_ptrace.data);
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);
case T_WRITEB_INS: /* special hack for patching text segments */
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 0
@ -125,18 +125,18 @@ int do_trace()
child->mp_ctime = 0;
#endif
r = sys_trace(req, child->mp_endpoint, m_in.PM_PTRACE_ADDR,
&m_in.PM_PTRACE_DATA);
r = sys_trace(req, child->mp_endpoint, m_in.m_lc_pm_ptrace.addr,
&m_in.m_lc_pm_ptrace.data);
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);
}
/* 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.
*/
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_tracer != who_p) return(ESRCH);
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. */
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
exit_proc(child, (int) m_in.PM_PTRACE_DATA,
exit_proc(child, m_in.m_lc_pm_ptrace.data,
FALSE /*dump_core*/);
/* Do not reply to the caller until VFS has processed the exit
@ -158,15 +158,15 @@ int do_trace()
return(SUSPEND);
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);
case T_GETRANGE:
case T_SETRANGE: /* get/set range of values */
r = sys_datacopy(who_e, (vir_bytes) m_in.PM_PTRACE_ADDR,
SELF, (vir_bytes) &pr, (phys_bytes) sizeof(pr));
r = sys_datacopy(who_e, m_in.m_lc_pm_ptrace.addr, SELF, (vir_bytes)&pr,
(phys_bytes)sizeof(pr));
if (r != OK) return(r);
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);
mp->mp_reply.PM_PTRACE_DATA = 0;
mp->mp_reply.m_pm_lc_ptrace.data = 0;
return(OK);
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);
child->mp_tracer = NO_TRACER;
@ -200,8 +200,8 @@ int do_trace()
}
}
if (m_in.PM_PTRACE_DATA > 0) { /* issue signal */
sig_proc(child, (int) m_in.PM_PTRACE_DATA, TRUE /*trace*/,
if (m_in.m_lc_pm_ptrace.data > 0) { /* issue signal */
sig_proc(child, m_in.m_lc_pm_ptrace.data, TRUE /*trace*/,
FALSE /* ksig */);
}
@ -216,11 +216,11 @@ int do_trace()
case T_RESUME:
case T_STEP:
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);
if (m_in.PM_PTRACE_DATA > 0) { /* issue signal */
sig_proc(child, (int) m_in.PM_PTRACE_DATA, FALSE /*trace*/,
if (m_in.m_lc_pm_ptrace.data > 0) { /* issue signal */
sig_proc(child, m_in.m_lc_pm_ptrace.data, FALSE /*trace*/,
FALSE /* ksig */);
}
@ -229,7 +229,7 @@ int do_trace()
*/
for (i = 1; i < _NSIG; 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);
}
}
@ -240,11 +240,11 @@ int do_trace()
break;
}
r = sys_trace(req, child->mp_endpoint, m_in.PM_PTRACE_ADDR,
&m_in.PM_PTRACE_DATA);
r = sys_trace(req, child->mp_endpoint, m_in.m_lc_pm_ptrace.addr,
&m_in.m_lc_pm_ptrace.data);
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);
}