Message type for PM_PTRACE
Change-Id: I19bbd5faa5c7511cda0239109b2ac55869c47b96
This commit is contained in:
parent
a5ed845b20
commit
345b3b5114
5 changed files with 56 additions and 43 deletions
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue