Loading arch/sh/include/asm/elf.h +9 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,15 @@ typedef struct user_fpu_struct elf_fpregset_t; #define elf_check_fdpic(x) ((x)->e_flags & EF_SH_FDPIC) #define elf_check_const_displacement(x) ((x)->e_flags & EF_SH_PIC) #if defined(CONFIG_SUPERH32) && \ (!defined(CONFIG_SH_FPU) && !defined(CONFIG_SH_DSP)) /* * Enable dump using regset for general purpose registers, use this as * the default once the FPU and DSP registers are moved over also. */ #define CORE_DUMP_USE_REGSET #endif #define USE_ELF_CORE_DUMP #define ELF_FDPIC_CORE_EFLAGS EF_SH_FDPIC #define ELF_EXEC_PAGESIZE PAGE_SIZE Loading arch/sh/include/asm/ptrace.h +7 −1 Original line number Diff line number Diff line Loading @@ -87,12 +87,18 @@ struct pt_dspregs { unsigned long mod; }; #define PTRACE_GETREGS 12 /* General registers */ #define PTRACE_SETREGS 13 #define PTRACE_GETFPREGS 14 /* FPU registers */ #define PTRACE_SETFPREGS 15 #define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */ #define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */ #define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */ #define PTRACE_GETDSPREGS 55 #define PTRACE_GETDSPREGS 55 /* DSP registers */ #define PTRACE_SETDSPREGS 56 #endif Loading arch/sh/kernel/ptrace_32.c +99 −17 Original line number Diff line number Diff line /* * linux/arch/sh/kernel/ptrace.c * SuperH process tracing * * Original x86 implementation: * By Ross Biro 1/23/92 * edited by Linus Torvalds * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka * Copyright (C) 2002 - 2008 Paul Mundt * * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka * Audit support: Yuichi Nakamura <ynakam@hitachisoft.jp> * Audit support by Yuichi Nakamura <ynakam@hitachisoft.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/sched.h> Loading @@ -22,6 +24,8 @@ #include <linux/audit.h> #include <linux/seccomp.h> #include <linux/tracehook.h> #include <linux/elf.h> #include <linux/regset.h> #include <asm/uaccess.h> #include <asm/pgtable.h> #include <asm/system.h> Loading @@ -29,11 +33,6 @@ #include <asm/mmu_context.h> #include <asm/syscalls.h> /* * does not yet catch signals sent when the child dies. * in exit.c or in signal.c. */ /* * This routine will get a word off of the process kernel stack. */ Loading Loading @@ -62,16 +61,12 @@ static inline int put_stack_long(struct task_struct *task, int offset, void user_enable_single_step(struct task_struct *child) { struct pt_regs *regs = task_pt_regs(child); long pc; pc = get_stack_long(child, (long)®s->pc); /* Next scheduling will set up UBC */ if (child->thread.ubc_pc == 0) ubc_usercnt += 1; child->thread.ubc_pc = pc; child->thread.ubc_pc = get_stack_long(child, offsetof(struct pt_regs, pc)); set_tsk_thread_flag(child, TIF_SINGLESTEP); } Loading Loading @@ -103,6 +98,83 @@ void ptrace_disable(struct task_struct *child) user_disable_single_step(child); } static int genregs_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { const struct pt_regs *regs = task_pt_regs(target); int ret; ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs->regs, 0, 16 * sizeof(unsigned long)); if (!ret) /* PC, PR, SR, GBR, MACH, MACL, TRA */ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, ®s->pc, offsetof(struct pt_regs, pc), sizeof(struct pt_regs)); if (!ret) ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, sizeof(struct pt_regs), -1); return ret; } 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; ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs->regs, 0, 16 * sizeof(unsigned long)); if (!ret && count > 0) ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®s->pc, offsetof(struct pt_regs, pc), sizeof(struct pt_regs)); if (!ret) ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, sizeof(struct pt_regs), -1); return ret; } /* * These are our native regset flavours. */ enum sh_regset { REGSET_GENERAL, }; static const struct user_regset sh_regsets[] = { /* * Format is: * R0 --> R15 * PC, PR, SR, GBR, MACH, MACL, TRA */ [REGSET_GENERAL] = { .core_note_type = NT_PRSTATUS, .n = ELF_NGREG, .size = sizeof(long), .align = sizeof(long), .get = genregs_get, .set = genregs_set, }, }; static const struct user_regset_view user_sh_native_view = { .name = "sh", .e_machine = EM_SH, .regsets = sh_regsets, .n = ARRAY_SIZE(sh_regsets), }; long arch_ptrace(struct task_struct *child, long request, long addr, long data) { struct user * dummy = NULL; Loading Loading @@ -159,6 +231,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) } break; case PTRACE_GETREGS: return copy_regset_to_user(child, &user_sh_native_view, REGSET_GENERAL, 0, sizeof(struct pt_regs), (void __user *)data); case PTRACE_SETREGS: return copy_regset_from_user(child, &user_sh_native_view, REGSET_GENERAL, 0, sizeof(struct pt_regs), (const void __user *)data); #ifdef CONFIG_SH_DSP case PTRACE_GETDSPREGS: { unsigned long dp; Loading Loading
arch/sh/include/asm/elf.h +9 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,15 @@ typedef struct user_fpu_struct elf_fpregset_t; #define elf_check_fdpic(x) ((x)->e_flags & EF_SH_FDPIC) #define elf_check_const_displacement(x) ((x)->e_flags & EF_SH_PIC) #if defined(CONFIG_SUPERH32) && \ (!defined(CONFIG_SH_FPU) && !defined(CONFIG_SH_DSP)) /* * Enable dump using regset for general purpose registers, use this as * the default once the FPU and DSP registers are moved over also. */ #define CORE_DUMP_USE_REGSET #endif #define USE_ELF_CORE_DUMP #define ELF_FDPIC_CORE_EFLAGS EF_SH_FDPIC #define ELF_EXEC_PAGESIZE PAGE_SIZE Loading
arch/sh/include/asm/ptrace.h +7 −1 Original line number Diff line number Diff line Loading @@ -87,12 +87,18 @@ struct pt_dspregs { unsigned long mod; }; #define PTRACE_GETREGS 12 /* General registers */ #define PTRACE_SETREGS 13 #define PTRACE_GETFPREGS 14 /* FPU registers */ #define PTRACE_SETFPREGS 15 #define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */ #define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */ #define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */ #define PTRACE_GETDSPREGS 55 #define PTRACE_GETDSPREGS 55 /* DSP registers */ #define PTRACE_SETDSPREGS 56 #endif Loading
arch/sh/kernel/ptrace_32.c +99 −17 Original line number Diff line number Diff line /* * linux/arch/sh/kernel/ptrace.c * SuperH process tracing * * Original x86 implementation: * By Ross Biro 1/23/92 * edited by Linus Torvalds * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka * Copyright (C) 2002 - 2008 Paul Mundt * * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka * Audit support: Yuichi Nakamura <ynakam@hitachisoft.jp> * Audit support by Yuichi Nakamura <ynakam@hitachisoft.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/sched.h> Loading @@ -22,6 +24,8 @@ #include <linux/audit.h> #include <linux/seccomp.h> #include <linux/tracehook.h> #include <linux/elf.h> #include <linux/regset.h> #include <asm/uaccess.h> #include <asm/pgtable.h> #include <asm/system.h> Loading @@ -29,11 +33,6 @@ #include <asm/mmu_context.h> #include <asm/syscalls.h> /* * does not yet catch signals sent when the child dies. * in exit.c or in signal.c. */ /* * This routine will get a word off of the process kernel stack. */ Loading Loading @@ -62,16 +61,12 @@ static inline int put_stack_long(struct task_struct *task, int offset, void user_enable_single_step(struct task_struct *child) { struct pt_regs *regs = task_pt_regs(child); long pc; pc = get_stack_long(child, (long)®s->pc); /* Next scheduling will set up UBC */ if (child->thread.ubc_pc == 0) ubc_usercnt += 1; child->thread.ubc_pc = pc; child->thread.ubc_pc = get_stack_long(child, offsetof(struct pt_regs, pc)); set_tsk_thread_flag(child, TIF_SINGLESTEP); } Loading Loading @@ -103,6 +98,83 @@ void ptrace_disable(struct task_struct *child) user_disable_single_step(child); } static int genregs_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { const struct pt_regs *regs = task_pt_regs(target); int ret; ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs->regs, 0, 16 * sizeof(unsigned long)); if (!ret) /* PC, PR, SR, GBR, MACH, MACL, TRA */ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, ®s->pc, offsetof(struct pt_regs, pc), sizeof(struct pt_regs)); if (!ret) ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, sizeof(struct pt_regs), -1); return ret; } 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; ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs->regs, 0, 16 * sizeof(unsigned long)); if (!ret && count > 0) ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®s->pc, offsetof(struct pt_regs, pc), sizeof(struct pt_regs)); if (!ret) ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, sizeof(struct pt_regs), -1); return ret; } /* * These are our native regset flavours. */ enum sh_regset { REGSET_GENERAL, }; static const struct user_regset sh_regsets[] = { /* * Format is: * R0 --> R15 * PC, PR, SR, GBR, MACH, MACL, TRA */ [REGSET_GENERAL] = { .core_note_type = NT_PRSTATUS, .n = ELF_NGREG, .size = sizeof(long), .align = sizeof(long), .get = genregs_get, .set = genregs_set, }, }; static const struct user_regset_view user_sh_native_view = { .name = "sh", .e_machine = EM_SH, .regsets = sh_regsets, .n = ARRAY_SIZE(sh_regsets), }; long arch_ptrace(struct task_struct *child, long request, long addr, long data) { struct user * dummy = NULL; Loading Loading @@ -159,6 +231,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) } break; case PTRACE_GETREGS: return copy_regset_to_user(child, &user_sh_native_view, REGSET_GENERAL, 0, sizeof(struct pt_regs), (void __user *)data); case PTRACE_SETREGS: return copy_regset_from_user(child, &user_sh_native_view, REGSET_GENERAL, 0, sizeof(struct pt_regs), (const void __user *)data); #ifdef CONFIG_SH_DSP case PTRACE_GETDSPREGS: { unsigned long dp; Loading