Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0
  2// Copyright (C) 2005-2017 Andes Technology Corporation
  3
  4#include <linux/ptrace.h>
  5#include <linux/regset.h>
  6#include <linux/tracehook.h>
  7#include <linux/elf.h>
  8#include <linux/sched/task_stack.h>
  9
 10enum nds32_regset {
 11	REGSET_GPR,
 12};
 13
 14static int gpr_get(struct task_struct *target,
 15		   const struct user_regset *regset,
 16		   struct membuf to)
 17{
 18	return membuf_write(&to, &task_pt_regs(target)->user_regs,
 19				sizeof(struct user_pt_regs));
 20}
 21
 22static int gpr_set(struct task_struct *target, const struct user_regset *regset,
 23		   unsigned int pos, unsigned int count,
 24		   const void *kbuf, const void __user * ubuf)
 25{
 26	int err;
 27	struct user_pt_regs newregs = task_pt_regs(target)->user_regs;
 28
 29	err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newregs, 0, -1);
 30	if (err)
 31		return err;
 32
 33	task_pt_regs(target)->user_regs = newregs;
 34	return 0;
 35}
 36
 37static const struct user_regset nds32_regsets[] = {
 38	[REGSET_GPR] = {
 39			.core_note_type = NT_PRSTATUS,
 40			.n = sizeof(struct user_pt_regs) / sizeof(u32),
 41			.size = sizeof(elf_greg_t),
 42			.align = sizeof(elf_greg_t),
 43			.regset_get = gpr_get,
 44			.set = gpr_set}
 45};
 46
 47static const struct user_regset_view nds32_user_view = {
 48	.name = "nds32",
 49	.e_machine = EM_NDS32,
 50	.regsets = nds32_regsets,
 51	.n = ARRAY_SIZE(nds32_regsets)
 52};
 53
 54const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 55{
 56	return &nds32_user_view;
 57}
 58
 59void ptrace_disable(struct task_struct *child)
 60{
 61	user_disable_single_step(child);
 62}
 63
 64/* do_ptrace()
 65 *
 66 * Provide ptrace defined service.
 67 */
 68long arch_ptrace(struct task_struct *child, long request, unsigned long addr,
 69		 unsigned long data)
 70{
 71	int ret = -EIO;
 72
 73	switch (request) {
 74	default:
 75		ret = ptrace_request(child, request, addr, data);
 76		break;
 77	}
 78
 79	return ret;
 80}
 81
 82void user_enable_single_step(struct task_struct *child)
 83{
 84	struct pt_regs *regs;
 85	regs = task_pt_regs(child);
 86	regs->ipsw |= PSW_mskHSS;
 87	set_tsk_thread_flag(child, TIF_SINGLESTEP);
 88}
 89
 90void user_disable_single_step(struct task_struct *child)
 91{
 92	struct pt_regs *regs;
 93	regs = task_pt_regs(child);
 94	regs->ipsw &= ~PSW_mskHSS;
 95	clear_tsk_thread_flag(child, TIF_SINGLESTEP);
 96}
 97
 98/* sys_trace()
 99 *
100 * syscall trace handler.
101 */
102
103asmlinkage int syscall_trace_enter(struct pt_regs *regs)
104{
105	if (test_thread_flag(TIF_SYSCALL_TRACE)) {
106		if (tracehook_report_syscall_entry(regs))
107			forget_syscall(regs);
108	}
109	return regs->syscallno;
110}
111
112asmlinkage void syscall_trace_leave(struct pt_regs *regs)
113{
114	int step = test_thread_flag(TIF_SINGLESTEP);
115	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
116		tracehook_report_syscall_exit(regs, step);
117
118}