/** @addtogroup tdebug
* @{
*/
/**
* @file
* @brief Task Debugging Syscalls.
*/
#include <proc/task.h>
#include <syscall/sysarg64.h>
#include <syscall/copy.h>
#include <console/klog.h>
#include <tdebug/tdebug.h>
#include <tdebug/systdebug.h>
/**
* Syscall to start debugging a task.
*
* The specified task (target) is attached to the current task (monitor).
* The monitoring task will be informed of debug events in the
* target task through IPC notifications with the specified method number.
*/
unative_t sys_tdebug_attach_task(sysarg64_t *uspace_taskid_arg,
unative_t method)
{
sysarg64_t taskid_arg;
int rc;
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
klog_printf("sys_tdebug_attach_task(%lld, %d)", taskid_arg.value, method);
return tdebug_attach_task(taskid_arg.value, method);
}
/**
* Syscall to stop debugging a task.
*/
unative_t sys_tdebug_detach_task(sysarg64_t *uspace_taskid_arg)
{
sysarg64_t taskid_arg;
int rc;
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
klog_printf("sys_tdebug_detach_task(%lld)", taskid_arg.value);
return tdebug_detach_task(taskid_arg.value);
}
/**
* Syscall to resume a thread stopped in a debugging event.
*/
unative_t sys_tdebug_continue_thread(sysarg64_t *uspace_threadid_arg)
{
sysarg64_t threadid_arg;
int rc;
rc = copy_from_uspace(&threadid_arg, uspace_threadid_arg,
sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
klog_printf("sys_tdebug_continue_thread(%lld)", threadid_arg.value);
return tdebug_continue_thread(threadid_arg.value);
}
/**
* Syscall to retrieve the arguments of a syscall.
*
* When a thread is stopped in a TDEBUG_EV_SYSCALL event,
* this function may be used to retrieve the arguments of the
* corresponding syscall.
*/
unative_t sys_tdebug_get_syscall_args(sysarg64_t *uspace_threadid_arg,
uintptr_t *uspace_buffer, unative_t *uspace_len_arg)
{
sysarg64_t threadid_arg;
unative_t len_arg;
unative_t sc_args[6];
int rc;
rc = copy_from_uspace(&threadid_arg, uspace_threadid_arg,
sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
rc = copy_from_uspace(&len_arg, uspace_len_arg, sizeof(unative_t));
if (rc != 0)
return (unative_t) rc;
klog_printf("sys_tdebug_get_syscall_args(%lld,...)", threadid_arg.value);
/* number of args to be copied */
if (len_arg > 6) len_arg = 6;
rc = tdebug_get_syscall_args(threadid_arg.value, sc_args);
if (rc != 0)
return (unative_t) rc;
rc = copy_to_uspace(uspace_buffer, sc_args, len_arg * sizeof(unative_t));
if (rc != 0)
return (unative_t) rc;
/* actual number of syscall args */
len_arg = 6;
rc = copy_to_uspace(uspace_len_arg, &len_arg, sizeof(unative_t));
if (rc != 0)
return (unative_t) rc;
klog_printf("success\n");
return 0;
}
unative_t sys_tdebug_set_event_mask(sysarg64_t *uspace_threadid_arg,
unative_t ev_mask)
{
sysarg64_t threadid_arg;
int rc;
rc = copy_from_uspace(&threadid_arg, uspace_threadid_arg,
sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
klog_printf("sys_tdebug_set_event_mask(%lld)", threadid_arg.value);
return tdebug_set_event_mask(threadid_arg.value, ev_mask);
}
unative_t sys_tdebug_stop_thread(sysarg64_t *uspace_threadid_arg)
{
sysarg64_t threadid_arg;
int rc;
rc = copy_from_uspace(&threadid_arg, uspace_threadid_arg,
sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
klog_printf("sys_tdebug_stop_thread(%lld)", threadid_arg.value);
return tdebug_stop_thread(threadid_arg.value);
}
unative_t sys_tdebug_stop_task(sysarg64_t *uspace_taskid_arg)
{
sysarg64_t taskid_arg;
int rc;
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
if (rc != 0)
return (unative_t) rc;
klog_printf("sys_tdebug_stop_task(%lld)", taskid_arg.value);
return tdebug_stop_task(taskid_arg.value);
}