Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 188507
b: refs/heads/master
c: e50e2f2
h: refs/heads/master
i:
  188505: 9e0eaf3
  188503: f50f782
v: v3
  • Loading branch information
Mike Frysinger committed Mar 9, 2010
1 parent fae80f8 commit 3fbac3e
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f2ce48024a9a6d3e92a023ded0f7b1e99da1cd16
refs/heads/master: e50e2f25c5b90abd00a1e5871c45094cf5207afc
8 changes: 7 additions & 1 deletion trunk/arch/blackfin/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
#define EF_BFIN_CODE_IN_L2 0x00000040 /* --code-in-l2 */
#define EF_BFIN_DATA_IN_L2 0x00000080 /* --data-in-l2 */

#if 1 /* core dumps not supported, but linux/elfcore.h needs these */
typedef unsigned long elf_greg_t;

#define ELF_NGREG 40 /* (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) */
#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];

typedef struct { } elf_fpregset_t;
#endif

/*
* This is used to ensure we don't load something for the wrong architecture.
*/
Expand Down Expand Up @@ -55,6 +58,9 @@ do { \
_regs->p2 = _dynamic_addr; \
} while(0)

#if 0
#define CORE_DUMP_USE_REGSET
#endif
#define ELF_FDPIC_CORE_EFLAGS EF_BFIN_FDPIC
#define ELF_EXEC_PAGESIZE 4096

Expand Down
7 changes: 0 additions & 7 deletions trunk/arch/blackfin/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,6 @@ void cpu_idle(void)
}
}

/* Fill in the fpu structure for a core dump. */

int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs)
{
return 1;
}

/*
* This gets run with P1 containing the
* function to call, and R1 containing
Expand Down
113 changes: 90 additions & 23 deletions trunk/arch/blackfin/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/elf.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/regset.h>
#include <linux/signal.h>
#include <linux/uaccess.h>

Expand Down Expand Up @@ -49,22 +51,6 @@ static inline struct pt_regs *task_pt_regs(struct task_struct *task)
(THREAD_SIZE - sizeof(struct pt_regs)));
}

/*
* Get all user integer registers.
*/
static inline int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
{
struct pt_regs regs;
memcpy(&regs, task_pt_regs(tsk), sizeof(regs));
regs.usp = tsk->thread.usp;
return copy_to_user(uregs, &regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
}

/* Mapping from PT_xxx to the stack offset at which the register is
* saved. Notice that usp has no stack-slot and needs to be treated
* specially (see get_reg/put_reg below).
*/

/*
* Get contents of register REGNO in task TASK.
*/
Expand Down Expand Up @@ -170,6 +156,84 @@ static inline int is_user_addr_valid(struct task_struct *child,
return -EIO;
}

/*
* retrieve the contents of Blackfin userspace general registers
*/
static int genregs_get(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
{
struct pt_regs *regs = task_pt_regs(target);
int ret;

/* This sucks ... */
regs->usp = target->thread.usp;

ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
regs, 0, sizeof(*regs));
if (ret < 0)
return ret;

return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
sizeof(*regs), -1);
}

/*
* update the contents of the Blackfin userspace general registers
*/
static int genregs_set(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
struct pt_regs *regs = task_pt_regs(target);
int ret;

/* Don't let people set SYSCFG (it's at the end of pt_regs) */
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
regs, 0, PT_SYSCFG);
if (ret < 0)
return ret;

/* This sucks ... */
target->thread.usp = regs->usp;
/* regs->retx = regs->pc; */

return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
PT_SYSCFG, -1);
}

/*
* Define the register sets available on the Blackfin under Linux
*/
enum bfin_regset {
REGSET_GENERAL,
};

static const struct user_regset bfin_regsets[] = {
[REGSET_GENERAL] = {
.core_note_type = NT_PRSTATUS,
.n = sizeof(struct pt_regs) / sizeof(long),
.size = sizeof(long),
.align = sizeof(long),
.get = genregs_get,
.set = genregs_set,
},
};

static const struct user_regset_view user_bfin_native_view = {
.name = "Blackfin",
.e_machine = EM_BLACKFIN,
.regsets = bfin_regsets,
.n = ARRAY_SIZE(bfin_regsets),
};

const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
return &user_bfin_native_view;
}

void ptrace_enable(struct task_struct *child)
{
struct pt_regs *regs = task_pt_regs(child);
Expand Down Expand Up @@ -327,15 +391,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;

case PTRACE_GETREGS:
/* Get all gp regs from the child. */
ret = ptrace_getregs(child, datap);
break;
pr_debug("ptrace: PTRACE_GETREGS\n");
return copy_regset_to_user(child, &user_bfin_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
(void __user *)data);

case PTRACE_SETREGS:
printk(KERN_WARNING "ptrace: SETREGS: **** NOT IMPLEMENTED ***\n");
/* Set all gp regs in the child. */
ret = 0;
break;
pr_debug("ptrace: PTRACE_SETREGS\n");
return copy_regset_from_user(child, &user_bfin_native_view,
REGSET_GENERAL,
0, sizeof(struct pt_regs),
(const void __user *)data);

default:
ret = ptrace_request(child, request, addr, data);
Expand Down

0 comments on commit 3fbac3e

Please sign in to comment.