Skip to content

Commit

Permalink
ptrace(): added get/set regs, peek/poke functions (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielinux committed Dec 13, 2016
1 parent 93dd5d5 commit 7b50021
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 27 deletions.
24 changes: 12 additions & 12 deletions kernel/bflt.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,11 @@ int process_relocs(struct flat_hdr * hdr, unsigned long * base, unsigned long da
*/

int bflt_load(uint8_t* from, void **reloc_text, void **reloc_data, void **reloc_bss,
void ** entry_point, size_t *stack_size, uint32_t *got_loc)
void ** entry_point, size_t *stack_size, uint32_t *got_loc, uint32_t *text_len, uint32_t *data_len)
{
struct flat_hdr hdr;
void * mem = NULL;
uint32_t text_len, data_len, bss_len, stack_len, flags, alloc_len, entry_point_offset;
uint32_t bss_len, stack_len, flags, alloc_len, entry_point_offset;
uint8_t *relocs_src, *text_src, *data_dest;
uint8_t *address_zero = from;
int32_t relocs, rev;
Expand All @@ -234,8 +234,8 @@ int bflt_load(uint8_t* from, void **reloc_text, void **reloc_data, void **reloc_
}

/* Calculate all the sizes */
text_len = long_be(hdr.data_start) - sizeof(struct flat_hdr);
data_len = long_be(hdr.data_end) - long_be(hdr.data_start);
*text_len = long_be(hdr.data_start) - sizeof(struct flat_hdr);
*data_len = long_be(hdr.data_end) - long_be(hdr.data_start);
bss_len = long_be(hdr.bss_end) - long_be(hdr.data_end);
stack_len = long_be(hdr.stack_size);
relocs = long_be(hdr.reloc_count);
Expand All @@ -255,7 +255,7 @@ int bflt_load(uint8_t* from, void **reloc_text, void **reloc_data, void **reloc_
alloc_len = relocs * sizeof(uint32_t);
else
alloc_len = bss_len;
alloc_len += data_len;
alloc_len += *data_len;


/*
Expand All @@ -271,12 +271,12 @@ int bflt_load(uint8_t* from, void **reloc_text, void **reloc_data, void **reloc_
if (flags & FLAT_FLAG_GOTPIC) {
uint8_t *mem, *copy_src;
uint32_t data_offset = 0;
uint32_t copy_len = data_len;
uint32_t copy_len = *data_len;

if (flags & FLAT_FLAG_RAM) {
alloc_len += text_len;
copy_len += text_len;
data_offset = text_len;
alloc_len += *text_len;
copy_len += *text_len;
data_offset = *text_len;
}

/* Allocate enough memory for .data, .bss and possibly .text */
Expand All @@ -293,19 +293,19 @@ int bflt_load(uint8_t* from, void **reloc_text, void **reloc_data, void **reloc_
copy_src = text_src;
} else {
*reloc_text = text_src;
copy_src = text_src + text_len;
copy_src = text_src + *text_len;
}
/* .data is always relocated */
data_dest = mem + data_offset;

*entry_point = *reloc_text + entry_point_offset;
*reloc_data = data_dest;
*reloc_bss = data_dest + data_len;
*reloc_bss = data_dest + *data_len;

/* copy segments .data segment and possibly .text */
memcpy(mem, copy_src, copy_len);
/* zero-init .bss */
memset(data_dest + data_len, 0, bss_len);
memset(data_dest + *data_len, 0, bss_len);
} else {
/* GZIP or FULL RAM bFLTs not supported for now */
kprintf("bFLT: Only GOTPIC bFLT binaries are supported\r\n");
Expand Down
2 changes: 1 addition & 1 deletion kernel/bflt.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
#define _BFLT_H_

int bflt_load(uint8_t* from, void **reloc_text, void **reloc_data, void **reloc_bss,
void **entry_point, size_t *stack_size, uint32_t *got_loc);
void **entry_point, size_t *stack_size, uint32_t *got_loc, uint32_t *text_len, uint32_t *data_len);

#endif
2 changes: 1 addition & 1 deletion kernel/drivers/xipfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ static void *xipfs_exe(struct fnode *fno, void *arg)
return NULL;

/* note: xip->init is bFLT load address! */
if (bflt_load((uint8_t*)xip->init, &reloc_text, &reloc_data, &reloc_bss, &init, &stack_size, (uint32_t *)&vfsi->pic))
if (bflt_load((uint8_t*)xip->init, &reloc_text, &reloc_data, &reloc_bss, &init, &stack_size, (uint32_t *)&vfsi->pic, &vfsi->text_size, &vfsi->data_size))
{
kprintf("xipfs: bFLT loading failed.\n");
return NULL;
Expand Down
97 changes: 84 additions & 13 deletions kernel/scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include "sys/pthread.h"
#include "poll.h"

#include "sys/user.h"

#define __inl inline
#define __naked __attribute__((naked))

Expand Down Expand Up @@ -2242,6 +2244,71 @@ enum __ptrace_request {
PTRACE_SEIZE = 0x4206
};

int ptrace_getregs(struct task *t, struct user *u)
{
struct extra_stack_frame *cur_extra = t->tb.sp + NVIC_FRAME_SIZE + EXTRA_FRAME_SIZE;
struct nvic_stack_frame *cur_nvic = t->tb.sp + EXTRA_FRAME_SIZE;
memcpy(&u->regs[0], cur_nvic, (4 * sizeof(uint32_t))); /* r0 - r3 */
memcpy(&u->regs[4], cur_extra, (8 * sizeof(uint32_t))); /* r4 - r11 */
u->regs[12] = cur_nvic->r12;
u->regs[13] = (uint32_t)(t->tb.sp);
u->regs[14] = cur_nvic->lr;
u->regs[15] = cur_nvic->pc;
u->regs[16] = cur_nvic->psr;
if (t->tb.vfsi) {
u->tsize = t->tb.vfsi->text_size;
u->dsize = t->tb.vfsi->data_size;
u->start_code = (uint32_t)t->tb.vfsi->init;
}
u->ssize = CONFIG_TASK_STACK_SIZE;
u->start_stack = (uint32_t)(t->tb.cur_stack);
u->signal = 0;
u->magic = 0xd0ab1e50;
return 0;
}

int ptrace_peekuser(struct task *t, uint32_t addr)
{
struct user u;
if (ptrace_getregs(t, &u) == 0)
return *(int *)(((char *)(&u)) + addr);
else return -1;
}

int ptrace_pokeuser(struct task *t, uint32_t addr, uint32_t data)
{
uint32_t *cur_extra = t->tb.sp + NVIC_FRAME_SIZE + EXTRA_FRAME_SIZE;
uint32_t *cur_nvic = t->tb.sp + EXTRA_FRAME_SIZE;
int pos = addr / 4;

if (addr > (16 * sizeof(uint32_t)))
return -1;
if ((addr % 4) != 0)
return -1;
if (pos < 4) {
cur_nvic[pos] = data;
return 0;
}
if (pos < 12) {
cur_extra[pos - 4] = data;
return 0;
}
if (pos == 12) {
cur_nvic[4] = data;
return 0;
}
return -1;
}

int ptrace_setregs(struct task *t, uint32_t *regs)
{
int i;
for (i = 0; i < 13; i++) {
ptrace_pokeuser(t, i * 4, regs[i]);
}
return 0;
}

int sys_ptrace_hdlr(uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4,
uint32_t arg5)

Expand All @@ -2254,12 +2321,15 @@ int sys_ptrace_hdlr(uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4,
struct task *tracee = NULL;

if (addr && task_ptr_valid(addr))
return -EACCES;
return -1;

/* Prepare tracee based on pid */
tracee = tasklist_get(&tasks_idling, pid);
if (!tracee)
tracee = tasklist_get(&tasks_running, pid);
if (!tracee) {
return -1;
}

switch (request) {
case PTRACE_TRACEME:
Expand All @@ -2270,60 +2340,61 @@ int sys_ptrace_hdlr(uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4,
return *((uint32_t *)addr);

case PTRACE_PEEKUSER:
break;
return ptrace_peekuser(tracee, (uint32_t)addr);
case PTRACE_POKETEXT:
break;
case PTRACE_POKEDATA:
break;
case PTRACE_POKEUSER:
break;
return ptrace_pokeuser(tracee, (uint32_t)addr, (uint32_t)data);
case PTRACE_CONT:
if (!tracee)
return -ENOENT;
return -1;
if (tracee->tb.tracer != _cur_task)
return -ESRCH;
return -1;
task_continue(tracee);
if ((int)data != 0)
task_kill(pid, (int)data);
return 0;

case PTRACE_KILL:
if (!tracee)
return -ENOENT;
return -1;
if (tracee->tb.tracer != _cur_task)
return -ESRCH;
return -1;
task_kill(pid, SIGKILL);
return 0;

case PTRACE_SINGLESTEP:
break;
case PTRACE_GETREGS:
return ptrace_getregs(tracee, (struct user *)data);
break;
case PTRACE_SETREGS:
return ptrace_setregs(tracee, (uint32_t *)data);
break;

case PTRACE_ATTACH:
case PTRACE_SEIZE:
if (!tracee)
return -ENOENT;
return -1;
tracee->tb.tracer = _cur_task;
if (request == PTRACE_ATTACH)
task_kill(pid, SIGSTOP);
return 0;

case PTRACE_DETACH:
if (!tracee)
return -ENOENT;
return -1;
if (tracee->tb.tracer != _cur_task)
return -ESRCH;
return -1;
tracee->tb.tracer = NULL;
task_kill(tracee->tb.pid, SIGCONT);
return 0;
case PTRACE_SYSCALL:
if (!tracee)
return -ENOENT;
return -1;
if (tracee->tb.tracer != _cur_task)
return -ESRCH;
return -1;
tracee->tb.flags |= TASK_FLAG_SYSCALL_STOP;
return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions kernel/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ struct vfs_info {
int pic;
void (*init)(void *);
void * allocated;
uint32_t text_size;
uint32_t data_size;
};


Expand Down

0 comments on commit 7b50021

Please sign in to comment.