285,6 → 285,159 |
ipc_answer(&TASK->kb.box, call); |
} |
|
|
|
/**************************/ |
/*** CHECKPOINTING ***/ |
/**************************/ |
|
|
static void udebug_receive_thread_get_thread_struct(call_t *call) |
{ |
unative_t to_copy; |
unative_t total_bytes; |
thread_t *t = (thread_t *)IPC_GET_ARG3(call->data); |
void *buffer; |
|
unative_t uspace_addr = IPC_GET_ARG2(call->data); |
size_t buf_size = IPC_GET_ARG4(call->data); |
|
if (buf_size < sizeof(thread_t)) |
{ |
to_copy = 0; |
total_bytes = sizeof(thread_t); |
} |
else |
{ |
udebug_thread_get_thread_struct(t, &buffer); |
to_copy = sizeof(thread_t); |
total_bytes = sizeof(thread_t); |
} |
|
IPC_SET_RETVAL(call->data, 0); |
IPC_SET_ARG1(call->data, uspace_addr); |
IPC_SET_ARG2(call->data, to_copy); |
IPC_SET_ARG3(call->data, total_bytes); |
|
if (to_copy > 0) |
call->buffer = buffer; |
else |
call->buffer = NULL; |
|
ipc_answer(&TASK->kb.box, call); |
} |
|
static void udebug_receive_thread_copy_kstack(call_t *call) |
{ |
void *buffer; |
unative_t uspace_addr = IPC_GET_ARG2(call->data); |
size_t buf_size = IPC_GET_ARG3(call->data); |
thread_t *t = (thread_t *)IPC_GET_ARG4(call->data); |
size_t copied; |
|
size_t kstack_size = PAGE_SIZE;//(uintptr_t)t->saved_context.sp - (uintptr_t)t->kstack; |
|
if (buf_size >= kstack_size) |
{ |
udebug_copy_kstack(t->kstack, &buffer, buf_size); |
copied = kstack_size; |
} |
else |
copied = 0; |
|
IPC_SET_RETVAL(call->data, 0); |
IPC_SET_ARG1(call->data, uspace_addr); |
IPC_SET_ARG2(call->data, copied); |
IPC_SET_ARG3(call->data, kstack_size); // needed |
|
if (copied > 0) |
call->buffer = (void *)buffer; |
else |
call->buffer = NULL; |
|
ipc_answer(&TASK->kb.box, call); |
} |
|
static void udebug_receive_task_mem_areas_read(call_t *call) |
{ |
unative_t uspace_addr; |
unative_t to_copy; |
unsigned total_bytes; |
unsigned buf_size; |
void *buffer; |
size_t n; |
int rc; |
|
uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */ |
buf_size = IPC_GET_ARG3(call->data); /* Dest. buffer size */ |
|
rc = udebug_task_get_memory_areas(&buffer, buf_size, &n); |
if (rc < 0) { |
IPC_SET_RETVAL(call->data, rc); |
ipc_answer(&TASK->kb.box, call); |
return; |
} |
|
total_bytes = n; |
|
/* Copy MAX(buf_size, total_bytes) bytes */ |
|
if (buf_size > total_bytes) |
to_copy = total_bytes; |
else |
to_copy = buf_size; |
|
/* |
* Make use of call->buffer to transfer data to caller's userspace |
*/ |
|
IPC_SET_RETVAL(call->data, 0); |
/* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that |
same code in process_answer() can be used |
(no way to distinguish method in answer) */ |
IPC_SET_ARG1(call->data, uspace_addr); |
IPC_SET_ARG2(call->data, to_copy); |
|
IPC_SET_ARG3(call->data, total_bytes); |
call->buffer = buffer; |
|
ipc_answer(&TASK->kb.box, call); |
} |
|
static void udebug_receive_mem_write(call_t *call) |
{ |
size_t size = (size_t)IPC_GET_ARG3(call->data); |
void *start = (void *)IPC_GET_ARG4(call->data); |
|
udebug_mem_write(call->buffer, start, size); |
|
IPC_SET_RETVAL(call->data, 0); |
ipc_answer(&TASK->kb.box, call); |
} |
|
static void udebug_receive_thread_restore_struct(call_t *call) |
{ |
thread_t *t = (thread_t *)IPC_GET_ARG3(call->data); |
|
udebug_restore_thread_struct(call->buffer, t); |
|
IPC_SET_RETVAL(call->data, 0); |
|
ipc_answer(&TASK->kb.box, call); |
} |
|
static void udebug_receive_restore_kstack(call_t *call) |
{ |
size_t size = (size_t)IPC_GET_ARG3(call->data); |
thread_t *t = (thread_t *)IPC_GET_ARG4(call->data); |
|
udebug_restore_kstack(call->buffer, size, t); |
|
IPC_SET_RETVAL(call->data, 0); |
ipc_answer(&TASK->kb.box, call); |
|
} |
|
/** Handle a debug call received on the kernel answerbox. |
* |
* This is called by the kbox servicing thread. Verifies that the sender |
336,6 → 489,26 |
case UDEBUG_M_MEM_READ: |
udebug_receive_mem_read(call); |
break; |
|
/* CHECKPOINTING */ |
case UDEBUG_M_TASK_MEM_AREAS_READ: |
udebug_receive_task_mem_areas_read(call); |
break; |
case UDEBUG_M_MEM_WRITE: |
udebug_receive_mem_write(call); |
break; |
case UDEBUG_M_THREAD_COPY_KSTACK: |
udebug_receive_thread_copy_kstack(call); |
break; |
case UDEBUG_M_RESTORE_KSTACK: |
udebug_receive_restore_kstack(call); |
break; |
case UDEBUG_M_THREAD_GET_THREAD_STRUCT: |
udebug_receive_thread_get_thread_struct(call); |
break; |
case UDEBUG_M_THREAD_RESTORE_THREAD_STRUCT: |
udebug_receive_thread_restore_struct(call); |
break; |
} |
} |
|