diff options
Diffstat (limited to 'arch/h8300/kernel/ptrace.c')
-rw-r--r-- | arch/h8300/kernel/ptrace.c | 200 |
1 files changed, 0 insertions, 200 deletions
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c deleted file mode 100644 index a11db009d0ea..000000000000 --- a/arch/h8300/kernel/ptrace.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * linux/arch/h8300/kernel/ptrace.c - * - * Copyright 2015 Yoshinori Sato <ysato@users.sourceforge.jp> - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file COPYING in the main directory of - * this archive for more details. - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/ptrace.h> -#include <linux/audit.h> -#include <linux/tracehook.h> -#include <linux/regset.h> -#include <linux/elf.h> - -#define CCR_MASK 0x6f /* mode/imask not set */ -#define EXR_MASK 0x80 /* modify only T */ - -#define PT_REG(r) offsetof(struct pt_regs, r) - -extern void user_disable_single_step(struct task_struct *child); - -/* 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). */ -static const int register_offset[] = { - PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4), - PT_REG(er5), PT_REG(er6), PT_REG(er0), -1, - PT_REG(orig_er0), PT_REG(ccr), PT_REG(pc), -#if defined(CONFIG_CPU_H8S) - PT_REG(exr), -#endif -}; - -/* read register */ -long h8300_get_reg(struct task_struct *task, int regno) -{ - switch (regno) { - case PT_USP: - return task->thread.usp + sizeof(long)*2; - case PT_CCR: - case PT_EXR: - return *(unsigned short *)(task->thread.esp0 + - register_offset[regno]); - default: - return *(unsigned long *)(task->thread.esp0 + - register_offset[regno]); - } -} - -int h8300_put_reg(struct task_struct *task, int regno, unsigned long data) -{ - unsigned short oldccr; - unsigned short oldexr; - - switch (regno) { - case PT_USP: - task->thread.usp = data - sizeof(long)*2; - case PT_CCR: - oldccr = *(unsigned short *)(task->thread.esp0 + - register_offset[regno]); - oldccr &= ~CCR_MASK; - data &= CCR_MASK; - data |= oldccr; - *(unsigned short *)(task->thread.esp0 + - register_offset[regno]) = data; - break; - case PT_EXR: - oldexr = *(unsigned short *)(task->thread.esp0 + - register_offset[regno]); - oldccr &= ~EXR_MASK; - data &= EXR_MASK; - data |= oldexr; - *(unsigned short *)(task->thread.esp0 + - register_offset[regno]) = data; - break; - default: - *(unsigned long *)(task->thread.esp0 + - register_offset[regno]) = data; - break; - } - return 0; -} - -static int regs_get(struct task_struct *target, - const struct user_regset *regset, - struct membuf to) -{ - int r; - - BUILD_BUG_ON(sizeof(struct user_regs_struct) % sizeof(long) != 0); - for (r = 0; r < ELF_NGREG; r++) - membuf_store(&to, h8300_get_reg(target, r)); - - return 0; -} - -static int regs_set(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - const void *kbuf, const void __user *ubuf) -{ - int r; - int ret; - struct user_regs_struct regs; - long *reg; - - /* build user regs in buffer */ - BUILD_BUG_ON(sizeof(regs) % sizeof(long) != 0); - for (reg = (long *)®s, r = 0; r < sizeof(regs) / sizeof(long); r++) - *reg++ = h8300_get_reg(target, r); - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - ®s, 0, sizeof(regs)); - if (ret) - return ret; - - /* write back to pt_regs */ - for (reg = (long *)®s, r = 0; r < sizeof(regs) / sizeof(long); r++) - h8300_put_reg(target, r, *reg++); - return 0; -} - -enum h8300_regset { - REGSET_GENERAL, -}; - -static const struct user_regset h8300_regsets[] = { - [REGSET_GENERAL] = { - .core_note_type = NT_PRSTATUS, - .n = ELF_NGREG, - .size = sizeof(long), - .align = sizeof(long), - .regset_get = regs_get, - .set = regs_set, - }, -}; - -static const struct user_regset_view user_h8300_native_view = { - .name = "h8300", - .e_machine = EM_H8_300, - .regsets = h8300_regsets, - .n = ARRAY_SIZE(h8300_regsets), -}; - -const struct user_regset_view *task_user_regset_view(struct task_struct *task) -{ - return &user_h8300_native_view; -} - -void ptrace_disable(struct task_struct *child) -{ - user_disable_single_step(child); -} - -long arch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - int ret; - - switch (request) { - default: - ret = ptrace_request(child, request, addr, data); - break; - } - return ret; -} - -asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) -{ - long ret = 0; - - if (test_thread_flag(TIF_SYSCALL_TRACE) && - tracehook_report_syscall_entry(regs)) - /* - * Tracing decided this syscall should not happen. - * We'll return a bogus call number to get an ENOSYS - * error, but leave the original number in regs->regs[0]. - */ - ret = -1L; - - audit_syscall_entry(regs->er1, regs->er2, regs->er3, - regs->er4, regs->er5); - - return ret ?: regs->er0; -} - -asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) -{ - int step; - - audit_syscall_exit(regs); - - step = test_thread_flag(TIF_SINGLESTEP); - if (step || test_thread_flag(TIF_SYSCALL_TRACE)) - tracehook_report_syscall_exit(regs, step); -} |