Received: by 10.223.164.202 with SMTP id h10csp1192235wrb; Tue, 7 Nov 2017 23:49:53 -0800 (PST) X-Google-Smtp-Source: ABhQp+S1/lTW8ChnYxSyFTo9xMHU2t0JIdLtIcHQhiLJRG8XlkjhiUlQhFm4pBD2TGoXbB5+kkEk X-Received: by 10.98.87.207 with SMTP id i76mr1650134pfj.134.1510127393695; Tue, 07 Nov 2017 23:49:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510127393; cv=none; d=google.com; s=arc-20160816; b=m67d8THt76kE+pftZKah0XD34Xcra242LwtpBhBMhwg5Ho2Fy11kSOThW+DtoJqHS6 SnIYn3llYVyeNQeLQ1bNvJLtKaPxEhlJKSyOP1UWOVNMjSWzvM0C3Shg62ww/6p5SV+l giBIwKXPH4TFWHx9neKze4RHh6aQImRluVcAeImewq6wj6uuR9LjB4LMcNbywS17Hzf+ leyiyIR1R7afTNWPtLgDwZprd9hOxsL2TP8E1KltLBJTrWJok/DkNvgEhRlfYRfYlrMO iYU34QikKIl6OyeUoAigKlOWOgDkfR0onuC4GidWDqlRWnZn1qk3GW7xunsHReU8aKmi mg8g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=ZauUSMvnPFKSkuOVirB9/uxbyJUj/3JryIWOwU3hc1s=; b=cIGTlkF4WWPiwdKaAQT48JSrHkHtNwXYRFb1kDzLIE9A6d+vZ2HMWalJGz8vbDS1KU Cc0AQN665T/pvIRIhfBWxfPqDB3knDdyysp6XZWfnzxfFD9v9evZFliSsQIstmMTkgKY InCrxy/C35cHa9+5sIBzbjJ6lNCruUS5ltf2G4MJ6plhmAcSxQKufAVfb2/TEHyJ5i+F 3HsifmHKHPahgRsisPtWDkIrHVN62ruer01g4LwQH97fhxXw5KDbXLU/OXTJ03tHPSlO APZMWEsW+aj4izanB0p1wkmvZS8lqvHQqIF6PLauvXIyzABRsTmB6BWMkJf+J9jvQ1u7 Z+sg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=mF73fUNQ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k13si3215750pgn.761.2017.11.07.23.49.41; Tue, 07 Nov 2017 23:49:53 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=mF73fUNQ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754218AbdKHGUz (ORCPT + 91 others); Wed, 8 Nov 2017 01:20:55 -0500 Received: from mail-pl0-f65.google.com ([209.85.160.65]:52952 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754094AbdKHGUp (ORCPT ); Wed, 8 Nov 2017 01:20:45 -0500 Received: by mail-pl0-f65.google.com with SMTP id z41so667840plh.9; Tue, 07 Nov 2017 22:20:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=ZauUSMvnPFKSkuOVirB9/uxbyJUj/3JryIWOwU3hc1s=; b=mF73fUNQ+3eeC+l+Ut80yrh0XPrFDOrUCrbGK3xehf4mAj79I/y1BuFTLCrYwdrv2i aDjX8/enroII593OOZt/6ka04nEzw1udwFAqFIlLx3RIPdz5+6vxjI+UxJRKkfyzivJv LlKffSYy2AunRkOpWzPNgvKB+kQTHiztwFCgnyB1u0FbORE8gYVLvvFdpHlIFooxiA1/ Se5I46brdwv05/MAAgonOw1R2lqWB8wNtrc2EDdFqKu57RPPLsPaDN5wZIZ+hTKfyJ/s ZBGuHe2cQEBbS1xwW3QAnKF+bdBjqAZhnlpjcJse/Qimsl3Q0aLXUldoKko3zKTmCwIQ qF+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=ZauUSMvnPFKSkuOVirB9/uxbyJUj/3JryIWOwU3hc1s=; b=WZixRm3XolkfBqo7ypwTrQEkTjBwJfzqKmY2Io2dfXn0OcUkylCz/tAUt2Llmq048/ VYLUKQ3etC8U329likQo6E2neYluzbBYl5FMwMvabMlGIMjoYgacwc4cPURy2ERgU36G VeP4c30dH3FvFpULOTL/ZaBO5Nl05I6RPhAtTYuWXK4LPGyj2nwt40+bbG3IA32/sAGm Z+Q2D8Ia4d+DW3v5+zXE1DRGFyFQo2pKCWkeRUWjTJnDD+IUWMhxicFv/t3BlltUO/74 INgCKMwYHHnZUcRLyqE0ILFfKPAR3i/Xd+P1NMgQ3WXVegIAnuKxJ5KEHKF/ObvR9g98 /7Gw== X-Gm-Message-State: AJaThX4jih3T3eK2YIaXkhpj3PcyPINWJ4stq5WWllaXMQxGUb+D86Fn VjWmtqXwWsb84pGeAC8qau4= X-Received: by 10.159.234.10 with SMTP id be10mr1260203plb.386.1510122044667; Tue, 07 Nov 2017 22:20:44 -0800 (PST) Received: from app09.andestech.com ([118.163.51.199]) by smtp.gmail.com with ESMTPSA id a4sm6581339pfj.72.2017.11.07.22.20.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 07 Nov 2017 22:20:44 -0800 (PST) From: Greentime Hu To: greentime@andestech.com, linux-kernel@vger.kernel.org, arnd@arndb.de, linux-arch@vger.kernel.org, tglx@linutronix.de, jason@lakedaemon.net, marc.zyngier@arm.com, robh+dt@kernel.org, netdev@vger.kernel.org Cc: green.hu@gmail.com, Vincent Chen Subject: [PATCH 19/31] nds32: Debugging support Date: Wed, 8 Nov 2017 13:55:07 +0800 Message-Id: <0d98a5eb51422ca3cd7854835fec46d58dd41b76.1510118606.git.green.hu@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Greentime Hu Signed-off-by: Vincent Chen Signed-off-by: Greentime Hu --- arch/nds32/include/uapi/asm/ptrace.h | 42 +++++ arch/nds32/kernel/ptrace.c | 325 ++++++++++++++++++++++++++++++++++ 2 files changed, 367 insertions(+) create mode 100644 arch/nds32/include/uapi/asm/ptrace.h create mode 100644 arch/nds32/kernel/ptrace.c diff --git a/arch/nds32/include/uapi/asm/ptrace.h b/arch/nds32/include/uapi/asm/ptrace.h new file mode 100644 index 0000000..20f9718 --- /dev/null +++ b/arch/nds32/include/uapi/asm/ptrace.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2005-2017 Andes Technology Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __UAPI_ASM_NDS32_PTRACE_H +#define __UAPI_ASM_NDS32_PTRACE_H + +#ifndef __ASSEMBLY__ + +/* + * User structures for general purpose register. + */ +struct user_pt_regs { + long uregs[26]; + long fp; + long gp; + long lp; + long sp; + long ipc; +#if defined(CONFIG_HWZOL) + long lb; + long le; + long lc; +#else + long dummy[3]; +#endif + long syscallno; +}; +#endif +#endif diff --git a/arch/nds32/kernel/ptrace.c b/arch/nds32/kernel/ptrace.c new file mode 100644 index 0000000..d91b3b8 --- /dev/null +++ b/arch/nds32/kernel/ptrace.c @@ -0,0 +1,325 @@ +/* + * Copyright (C) 2005-2017 Andes Technology Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +enum nds32_regset { + REGSET_GPR, +}; + +static int gpr_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user * ubuf) +{ + struct user_pt_regs *uregs = &task_pt_regs(target)->user_regs; + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, -1); +} + +static int gpr_set(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user * ubuf) +{ + int err; + struct user_pt_regs newregs = task_pt_regs(target)->user_regs; + + err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newregs, 0, -1); + if (err) + return err; + + task_pt_regs(target)->user_regs = newregs; + return 0; +} + +static const struct user_regset nds32_regsets[] = { + [REGSET_GPR] = { + .core_note_type = NT_PRSTATUS, + .n = sizeof(struct user_pt_regs) / sizeof(u32), + .size = sizeof(u32), + .align = sizeof(u32), + .get = gpr_get, + .set = gpr_set} +}; + +static const struct user_regset_view nds32_user_view = { + .name = "nds32",.e_machine = EM_NDS32, + .regsets = nds32_regsets,.n = ARRAY_SIZE(nds32_regsets) +}; + +const struct user_regset_view *task_user_regset_view(struct task_struct *task) +{ + return &nds32_user_view; +} + +/* get_user_reg() + * + * This routine will get a word off of the processes privileged stack. + * the offset is how far from the base addr as stored in the THREAD. + * this routine assumes that all the privileged stacks are in our + * data space. + */ +static inline unsigned int get_user_reg(struct task_struct *task, int offset) +{ + return task_pt_regs(task)->uregs[offset]; +} + +/* put_user_reg() + * + * this routine will put a word on the processes privileged stack. + * the offset is how far from the base addr as stored in the THREAD. + * this routine assumes that all the privileged stacks are in our + * data space. + */ +static inline int put_user_reg(struct task_struct *task, int offset, long data) +{ + struct pt_regs newregs, *regs = task_pt_regs(task); + int ret = -EINVAL; + + newregs = *regs; + newregs.uregs[offset] = data; + + if (valid_user_regs(&newregs)) { + regs->uregs[offset] = data; + ret = 0; + } + + return ret; +} + +/* + * Called by kernel/ptrace.c when detaching.. + * + * Make sure the single step bit is not set. + */ +void ptrace_disable(struct task_struct *child) +{ + user_disable_single_step(child); +} + +static void fill_sigtrap_info(struct task_struct *tsk, + struct pt_regs *regs, + int error_code, int si_code, struct siginfo *info) +{ + tsk->thread.trap_no = ENTRY_DEBUG_RELATED; + tsk->thread.error_code = error_code; + + memset(info, 0, sizeof(*info)); + info->si_signo = SIGTRAP; + info->si_code = si_code; + info->si_addr = (void __user *)instruction_pointer(regs); +} + +void user_single_step_siginfo(struct task_struct *tsk, + struct pt_regs *regs, struct siginfo *info) +{ + fill_sigtrap_info(tsk, regs, 0, TRAP_BRKPT, info); +} + +/* + * Handle hitting a breakpoint. + */ +void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, + int error_code, int si_code) +{ + struct siginfo info; + + fill_sigtrap_info(tsk, regs, error_code, TRAP_BRKPT, &info); + /* Send us the fake SIGTRAP */ + force_sig_info(SIGTRAP, &info, tsk); +} + +/* ptrace_read_user() + * + * Read the word at offset "off" into the "struct user". We + * actually access the pt_regs stored on the kernel stack. + */ +static int +ptrace_read_user(struct task_struct *tsk, unsigned long off, + unsigned long __user * ret) +{ + unsigned long tmp = 0; + + if (off < sizeof(struct pt_regs)) { + if (off & 3) + return -EIO; + tmp = get_user_reg(tsk, off >> 2); + return put_user(tmp, ret); + } else + return -EIO; +} + +/* ptrace_write_user() + * + * Write the word at offset "off" into "struct user". We + * actually access the pt_regs stored on the kernel stack. + */ +static int +ptrace_write_user(struct task_struct *tsk, unsigned long off, unsigned long val) +{ + if (off < sizeof(struct pt_regs)) { + if (off & 3) + return -EIO; + return put_user_reg(tsk, off >> 2, val); + } else + return -EIO; +} + +/* ptrace_getregs() + * + * Get all user integer registers. + */ +static int ptrace_getregs(struct task_struct *tsk, void __user * uregs) +{ + struct pt_regs *regs = task_pt_regs(tsk); + + return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0; +} + +/* ptrace_setregs() + * + * Set all user integer registers. + */ +static int ptrace_setregs(struct task_struct *tsk, void __user * uregs) +{ + struct pt_regs newregs; + int ret; + + ret = -EFAULT; + if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) { + struct pt_regs *regs = task_pt_regs(tsk); + + ret = -EINVAL; + if (valid_user_regs(&newregs)) { + *regs = newregs; + ret = 0; + } + } + + return ret; +} + +/* ptrace_getfpregs() + * + * Get the child FPU state. + */ +static int ptrace_getfpregs(struct task_struct *tsk, void __user * ufpregs) +{ + return -EFAULT; +} + +/* + * Set the child FPU state. + */ +static int ptrace_setfpregs(struct task_struct *tsk, void __user * ufpregs) +{ + return -EFAULT; +} + +/* do_ptrace() + * + * Provide ptrace defined service. + */ +long arch_ptrace(struct task_struct *child, long request, unsigned long addr, + unsigned long data) +{ + int ret; + + switch (request) { + case PTRACE_PEEKUSR: + ret = + ptrace_read_user(child, addr, (unsigned long __user *)data); + break; + + case PTRACE_POKEUSR: + ret = ptrace_write_user(child, addr, data); + break; + + case PTRACE_GETREGS: + ret = ptrace_getregs(child, (void __user *)data); + break; + + case PTRACE_SETREGS: + ret = ptrace_setregs(child, (void __user *)data); + break; + + case PTRACE_GETFPREGS: + ret = ptrace_getfpregs(child, (void __user *)data); + break; + + case PTRACE_SETFPREGS: + ret = ptrace_setfpregs(child, (void __user *)data); + break; + + default: + ret = ptrace_request(child, request, addr, data); + break; + } + + return ret; +} + +void user_enable_single_step(struct task_struct *child) +{ + struct pt_regs *regs; + regs = task_pt_regs(child); + regs->ipsw |= PSW_mskHSS; + set_tsk_thread_flag(child, TIF_SINGLESTEP); +} + +void user_disable_single_step(struct task_struct *child) +{ + struct pt_regs *regs; + regs = task_pt_regs(child); + regs->ipsw &= ~PSW_mskHSS; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); +} + +/* sys_trace() + * + * syscall trace handler. + */ + +asmlinkage int syscall_trace_enter(int syscall, struct pt_regs *regs) +{ + if (test_thread_flag(TIF_SYSCALL_TRACE)) { + if (tracehook_report_syscall_entry(regs)) + return -1; + } + return syscall; +} + +asmlinkage void syscall_trace_leave(struct pt_regs *regs) +{ + int step = test_thread_flag(TIF_SINGLESTEP); + if (step || test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, step); + +} -- 1.7.9.5 From 1584465518295257001@xxx Sun Nov 19 04:01:10 +0000 2017 X-GM-THRID: 1584465518295257001 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread