From: Richard Kuo <rkuo@codeaurora.org>
To: linux-kernel@vger.kernel.org, linux-hexagon@vger.kernel.org
Subject: [patch 19/36] Hexagon: Add ptrace support
Date: Wed, 17 Aug 2011 11:35:16 -0500 [thread overview]
Message-ID: <20110817163521.637768691@codeaurora.org> (raw)
In-Reply-To: 20110817163457.878854582@codeaurora.org
[-- Attachment #1: ptrace.diff --]
[-- Type: text/plain, Size: 12397 bytes --]
Signed-off-by: Richard Kuo <rkuo@codeaurora.org>
---
arch/hexagon/include/asm/ptrace.h | 90 +++++++
arch/hexagon/kernel/ptrace.c | 437 ++++++++++++++++++++++++++++++++++++++
2 files changed, 527 insertions(+)
Index: linux-hexagon-kernel/arch/hexagon/include/asm/ptrace.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-hexagon-kernel/arch/hexagon/include/asm/ptrace.h 2011-07-20 15:19:41.335152144 -0500
@@ -0,0 +1,90 @@
+/*
+ * Ptrace definitions for the Hexagon architecture
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+#include <asm/registers.h>
+
+/* arch_ptrace and ptrace_disable use task_struct in arg lists */
+struct task_struct;
+
+/*
+ * ptrace commands not part of Linux base set (but common to essentially
+ * all supported architectures).
+ */
+
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+
+/*
+ * Register numbers used in ptrace calls. 0-31 represent GPRs R0-R31
+ */
+#define PT_R0 0
+#define PT_R1 1
+#define PT_R2 2
+#define PT_R3 3
+#define PT_R4 4
+#define PT_R5 5
+#define PT_R6 6
+#define PT_R7 7
+#define PT_R8 8
+#define PT_R9 9
+#define PT_R10 10
+#define PT_R11 11
+#define PT_R12 12
+#define PT_R13 13
+#define PT_R14 14
+#define PT_R15 15
+#define PT_R16 16
+#define PT_R17 17
+#define PT_R18 18
+#define PT_R19 19
+#define PT_R20 20
+#define PT_R21 21
+#define PT_R22 22
+#define PT_R23 23
+#define PT_R24 24
+#define PT_R25 25
+#define PT_R26 26
+#define PT_R27 27
+#define PT_R28 28
+#define PT_R29 29
+#define PT_R30 30
+#define PT_R31 31
+#define PT_GP 32
+#define PT_UGP 33
+#define PT_SA0 34
+#define PT_LC0 35
+#define PT_SA1 36
+#define PT_LC1 37
+#define PT_M0 38
+#define PT_M1 39
+#define PT_PREDS 40
+#define PT_PC 41
+#define PT_CAUSE 42
+#define PT_BADVA 43
+
+#define N_PTRACE_REGS 44
+
+#define profile_pc(regs) instruction_pointer(regs)
+#define instruction_pointer(regs) pt_elr(regs)
+
+#endif
Index: linux-hexagon-kernel/arch/hexagon/kernel/ptrace.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-hexagon-kernel/arch/hexagon/kernel/ptrace.c 2011-07-20 15:19:41.335152144 -0500
@@ -0,0 +1,437 @@
+/*
+ * Ptrace support for Hexagon
+ *
+ * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/cacheflush.h>
+
+/* ToDo: see include/linux/regset.h */
+
+void ptrace_disable(struct task_struct *child)
+{
+ /* Boilerplate - resolves to null inline if no HW single-step */
+ user_disable_single_step(child);
+}
+
+/*
+ * Examine a specific register of a task
+ */
+static int ptrace_peekusr(struct task_struct *child, int regnum,
+ void __user *data)
+{
+ struct pt_regs *regs = task_pt_regs(child);
+ unsigned long tmp;
+
+ switch (regnum) {
+ case PT_R0:
+ tmp = regs->r00;
+ break;
+ case PT_R1:
+ tmp = regs->r01;
+ break;
+ case PT_R2:
+ tmp = regs->r02;
+ break;
+ case PT_R3:
+ tmp = regs->r03;
+ break;
+ case PT_R4:
+ tmp = regs->r04;
+ break;
+ case PT_R5:
+ tmp = regs->r05;
+ break;
+ case PT_R6:
+ tmp = regs->r06;
+ break;
+ case PT_R7:
+ tmp = regs->r07;
+ break;
+ case PT_R8:
+ tmp = regs->r08;
+ break;
+ case PT_R9:
+ tmp = regs->r09;
+ break;
+ case PT_R10:
+ tmp = regs->r10;
+ break;
+ case PT_R11:
+ tmp = regs->r11;
+ break;
+ case PT_R12:
+ tmp = regs->r12;
+ break;
+ case PT_R13:
+ tmp = regs->r13;
+ break;
+ case PT_R14:
+ tmp = regs->r14;
+ break;
+ case PT_R15:
+ tmp = regs->r15;
+ break;
+ case PT_R16:
+ tmp = regs->r16;
+ break;
+ case PT_R17:
+ tmp = regs->r17;
+ break;
+ case PT_R18:
+ tmp = regs->r18;
+ break;
+ case PT_R19:
+ tmp = regs->r19;
+ break;
+ case PT_R20:
+ tmp = regs->r20;
+ break;
+ case PT_R21:
+ tmp = regs->r21;
+ break;
+ case PT_R22:
+ tmp = regs->r22;
+ break;
+ case PT_R23:
+ tmp = regs->r23;
+ break;
+ case PT_R24:
+ tmp = regs->r24;
+ break;
+ case PT_R25:
+ tmp = regs->r25;
+ break;
+ case PT_R26:
+ tmp = regs->r26;
+ break;
+ case PT_R27:
+ tmp = regs->r27;
+ break;
+ case PT_R28:
+ tmp = regs->r28;
+ break;
+ case PT_R29:
+ tmp = regs->r29;
+ break;
+ case PT_R30:
+ tmp = regs->r30;
+ break;
+ case PT_R31:
+ tmp = regs->r31;
+ break;
+ case PT_GP:
+ tmp = regs->gp;
+ break;
+ case PT_UGP:
+ tmp = regs->ugp;
+ break;
+ case PT_SA0:
+ tmp = regs->sa0;
+ break;
+ case PT_LC0:
+ tmp = regs->lc0;
+ break;
+ case PT_SA1:
+ tmp = regs->sa1;
+ break;
+ case PT_LC1:
+ tmp = regs->lc1;
+ break;
+ case PT_M0:
+ tmp = regs->m0;
+ break;
+ case PT_M1:
+ tmp = regs->m1;
+ break;
+ case PT_PREDS:
+ tmp = regs->preds;
+ break;
+ case PT_PC:
+ tmp = pt_elr(regs);
+ break;
+ case PT_CAUSE:
+ tmp = pt_cause(regs);
+ break;
+ case PT_BADVA:
+ tmp = pt_badva(regs);
+ break;
+ default:
+ return -EIO;
+ }
+ return put_user(tmp, (unsigned long __user *)data);
+}
+
+/*
+ * Modify a specific register of a task. CAUSE and BADVA aren't writeable.
+ */
+static int ptrace_pokeusr(struct task_struct *child, int regnum,
+ unsigned long data)
+{
+ struct pt_regs *regs = task_pt_regs(child);
+
+ switch (regnum) {
+ case PT_R0:
+ regs->r00 = data;
+ break;
+ case PT_R1:
+ regs->r01 = data;
+ break;
+ case PT_R2:
+ regs->r02 = data;
+ break;
+ case PT_R3:
+ regs->r03 = data;
+ break;
+ case PT_R4:
+ regs->r04 = data;
+ break;
+ case PT_R5:
+ regs->r05 = data;
+ break;
+ case PT_R6:
+ regs->r06 = data;
+ break;
+ case PT_R7:
+ regs->r07 = data;
+ break;
+ case PT_R8:
+ regs->r08 = data;
+ break;
+ case PT_R9:
+ regs->r09 = data;
+ break;
+ case PT_R10:
+ regs->r10 = data;
+ break;
+ case PT_R11:
+ regs->r11 = data;
+ break;
+ case PT_R12:
+ regs->r12 = data;
+ break;
+ case PT_R13:
+ regs->r13 = data;
+ break;
+ case PT_R14:
+ regs->r14 = data;
+ break;
+ case PT_R15:
+ regs->r15 = data;
+ break;
+ case PT_R16:
+ regs->r16 = data;
+ break;
+ case PT_R17:
+ regs->r17 = data;
+ break;
+ case PT_R18:
+ regs->r18 = data;
+ break;
+ case PT_R19:
+ regs->r19 = data;
+ break;
+ case PT_R20:
+ regs->r20 = data;
+ break;
+ case PT_R21:
+ regs->r21 = data;
+ break;
+ case PT_R22:
+ regs->r22 = data;
+ break;
+ case PT_R23:
+ regs->r23 = data;
+ break;
+ case PT_R24:
+ regs->r24 = data;
+ break;
+ case PT_R25:
+ regs->r25 = data;
+ break;
+ case PT_R26:
+ regs->r26 = data;
+ break;
+ case PT_R27:
+ regs->r27 = data;
+ break;
+ case PT_R28:
+ regs->r28 = data;
+ break;
+ case PT_R29:
+ regs->r29 = data;
+ /*
+ * This is special; SP is actually restored by the VM via the
+ * special event record which is set by the special trap.
+ */
+ regs->hvmer.vmpsp = data;
+ break;
+ case PT_R30:
+ regs->r30 = data;
+ break;
+ case PT_R31:
+ regs->r31 = data;
+ break;
+ case PT_GP:
+ regs->gp = data;
+ break;
+ case PT_UGP:
+ regs->ugp = data;
+ break;
+ case PT_SA0:
+ regs->sa0 = data;
+ break;
+ case PT_LC0:
+ regs->lc0 = data;
+ break;
+ case PT_SA1:
+ regs->sa1 = data;
+ break;
+ case PT_LC1:
+ regs->lc1 = data;
+ break;
+ case PT_M0:
+ regs->m0 = data;
+ break;
+ case PT_M1:
+ regs->m1 = data;
+ break;
+ case PT_PREDS:
+ regs->preds = data;
+ break;
+ case PT_PC:
+ pt_elr(regs) = data;
+ break;
+ default:
+ return -EIO;
+ }
+ return 0;
+}
+
+#define reg_acc(err, fn, reg, offset) \
+ do { \
+ err = fn(reg, offset); \
+ if (err) \
+ return err; \
+ } while (0)
+
+/*
+ * Read the full register set of a task. Layout is *not* the same
+ * as pt_regs, but is instead an array of longs whose indices are
+ * defined in ptrace.h.
+ */
+int ptrace_getregs(struct task_struct *child, unsigned long __user *data)
+{
+ struct pt_regs *regs = task_pt_regs(child);
+ int err;
+ int i;
+
+ if (!access_ok(VERIFY_WRITE, data, N_PTRACE_REGS * sizeof(long)))
+ return -EIO;
+
+ for (i = 0; i < 32; i++)
+ reg_acc(err, __put_user, *((unsigned long *)(®s->r0100) + i),
+ data + i);
+
+ reg_acc(err, __put_user, regs->gp, data + PT_GP);
+ reg_acc(err, __put_user, regs->ugp, data + PT_UGP);
+ reg_acc(err, __put_user, regs->sa0, data + PT_SA0);
+ reg_acc(err, __put_user, regs->lc0, data + PT_LC0);
+ reg_acc(err, __put_user, regs->sa1, data + PT_SA1);
+ reg_acc(err, __put_user, regs->lc1, data + PT_LC1);
+ reg_acc(err, __put_user, regs->m0, data + PT_M0);
+ reg_acc(err, __put_user, regs->m1, data + PT_M1);
+ reg_acc(err, __put_user, regs->preds, data + PT_PREDS);
+ reg_acc(err, __put_user, pt_elr(regs), data + PT_PC);
+ reg_acc(err, __put_user, pt_cause(regs), data + PT_CAUSE);
+ reg_acc(err, __put_user, pt_badva(regs), data + PT_BADVA);
+
+ return 0;
+}
+
+/*
+ * Write the full register set of a task, with same layout as ptrace_getregs.
+ * BADVA and CAUSE aren't modifiable, however.
+ */
+int ptrace_setregs(struct task_struct *child, unsigned long __user *data)
+{
+ struct pt_regs *regs = task_pt_regs(child);
+ int i;
+ int err;
+
+ if (!access_ok(VERIFY_READ, data, (N_PTRACE_REGS - 2) * sizeof(long)))
+ return -EIO;
+
+ for (i = 0; i < 32; i++)
+ reg_acc(err, __get_user, *((unsigned long *)(®s->r0100) + i),
+ data + i);
+
+ reg_acc(err, __get_user, regs->gp, data + PT_GP);
+ reg_acc(err, __get_user, regs->ugp, data + PT_UGP);
+ reg_acc(err, __get_user, regs->sa0, data + PT_SA0);
+ reg_acc(err, __get_user, regs->lc0, data + PT_LC0);
+ reg_acc(err, __get_user, regs->sa1, data + PT_SA1);
+ reg_acc(err, __get_user, regs->lc1, data + PT_LC1);
+ reg_acc(err, __get_user, regs->m0, data + PT_M0);
+ reg_acc(err, __get_user, regs->m1, data + PT_M1);
+ reg_acc(err, __get_user, regs->preds, data + PT_PREDS);
+ reg_acc(err, __get_user, pt_elr(regs), data + PT_PC);
+
+ return 0;
+}
+
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
+{
+ int ret;
+
+ switch (request) {
+ case PTRACE_PEEKUSR: /* read register specified by addr. */
+ ret = ptrace_peekusr(child, addr, (void __user *) data);
+ break;
+ case PTRACE_POKETEXT: /* write the word at location addr. */
+ case PTRACE_POKEDATA:
+ ret = generic_ptrace_pokedata(child, addr, data);
+ break;
+ case PTRACE_POKEUSR: /* write register specified by addr. */
+ ret = ptrace_pokeusr(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;
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ }
+
+ return ret;
+}
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
next prev parent reply other threads:[~2011-08-17 16:35 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-17 16:34 [patch 00/36] Hexagon: Add support for Qualcomm Hexagon architecture Richard Kuo
2011-08-17 16:34 ` [patch 01/36] Hexagon: Add generic headers Richard Kuo
2011-08-17 19:19 ` Arnd Bergmann
2011-08-17 16:34 ` [patch 02/36] Hexagon: Core arch-specific header files Richard Kuo
2011-08-17 19:19 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 03/36] Hexagon: Add bitops support Richard Kuo
2011-08-17 19:19 ` Arnd Bergmann
2011-08-26 20:34 ` Pavel Machek
2011-08-30 21:14 ` ARM assembly syntax (was Re: [patch 03/36] Hexagon: Add bitops support) Linas Vepstas (Code Aurora)
2011-09-02 16:53 ` Pavel Machek
2011-08-30 21:59 ` [patch 03/36] Hexagon: Add bitops support Måns Rullgård
2011-08-17 16:35 ` [patch 04/36] Hexagon: Add atomic ops support Richard Kuo
2011-08-17 19:20 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 05/36] Hexagon: Add syscalls Richard Kuo
2011-08-17 19:29 ` Arnd Bergmann
2011-08-17 20:12 ` Jonas Bonn
2011-08-17 20:12 ` Jonas Bonn
2011-08-17 16:35 ` [patch 06/36] Hexagon: Add processor and system headers Richard Kuo
2011-08-17 19:31 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 07/36] Hexagon: Add threadinfo Richard Kuo
2011-08-17 19:37 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 08/36] Hexagon: Add delay functions Richard Kuo
2011-08-17 19:38 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 09/36] Hexagon: Add checksum functions Richard Kuo
2011-08-17 19:40 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 10/36] Hexagon: Add memcpy and memset accelerated functions Richard Kuo
2011-08-17 16:35 ` [patch 11/36] Hexagon: Add hypervisor interface Richard Kuo
2011-08-17 16:35 ` [patch 12/36] Hexagon: Export ksyms defined in assembly files Richard Kuo
2011-08-17 16:35 ` [patch 13/36] Hexagon: Support dynamic module loading Richard Kuo
2011-08-17 19:41 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 14/36] Hexagon: Add signal functions Richard Kuo
2012-02-11 23:27 ` hexagon: signal handling bugs Al Viro
2012-02-15 17:45 ` Richard Kuo
2012-02-15 18:18 ` Linas Vepstas
2011-08-17 16:35 ` [patch 15/36] Hexagon: Add init_task and process functions Richard Kuo
2011-08-17 19:45 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 16/36] Hexagon: Add startup code Richard Kuo
2011-08-17 16:35 ` [patch 17/36] Hexagon: Add interrupts Richard Kuo
2011-08-17 16:35 ` [patch 18/36] Hexagon: Add time and timer functions Richard Kuo
2011-08-17 16:35 ` Richard Kuo [this message]
2011-08-17 19:47 ` [patch 19/36] Hexagon: Add ptrace support Arnd Bergmann
2011-08-17 16:35 ` [patch 20/36] Hexagon: Provide basic debugging and system trap support Richard Kuo
2011-08-17 16:35 ` [patch 21/36] Hexagon: Add SMP support Richard Kuo
2011-08-17 16:35 ` [patch 22/36] Hexagon: Add locking types and functions Richard Kuo
2011-08-17 16:35 ` [patch 23/36] Hexagon: Add user access functions Richard Kuo
2011-08-17 16:35 ` [patch 24/36] Hexagon: Provide basic implementation and/or stubs for I/O routines Richard Kuo
2011-08-17 19:55 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 25/36] Hexagon: Implement basic cache-flush support Richard Kuo
2011-08-17 16:35 ` [patch 26/36] Hexagon: Implement basic TLB management routines for Hexagon Richard Kuo
2011-08-17 16:35 ` [patch 27/36] Hexagon: Provide DMA implementation Richard Kuo
2011-08-17 20:01 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 28/36] Hexagon: Add ioremap support Richard Kuo
2011-08-17 16:35 ` [patch 29/36] Hexagon: Add page table header files & etc Richard Kuo
2011-08-17 16:35 ` [patch 30/36] Hexagon: Add page-fault support Richard Kuo
2011-08-17 16:35 ` [patch 31/36] Hexagon: kgdb support files Richard Kuo
2011-08-17 16:35 ` [patch 32/36] Hexagon: Comet platform support Richard Kuo
2011-08-17 20:07 ` Arnd Bergmann
2011-08-17 23:45 ` Linas Vepstas
2011-08-17 20:08 ` David Brown
2011-08-17 16:35 ` [patch 33/36] Hexagon: Platform-generic support Richard Kuo
2011-08-17 20:20 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 34/36] Hexagon: Add configuration and makefiles for the Hexagon architecture Richard Kuo
2011-08-17 20:27 ` Arnd Bergmann
2011-08-17 16:35 ` [patch 35/36] Hexagon: Add basic stacktrace functionality for " Richard Kuo
2011-08-17 16:35 ` [patch 36/36] Hexagon: Add self to MAINTAINERS Richard Kuo
2011-08-17 19:00 ` [patch 00/36] Hexagon: Add support for Qualcomm Hexagon architecture Zan Lynx
2011-08-17 19:42 ` Richard Kuo
2011-08-17 20:34 ` Arnd Bergmann
2011-08-18 0:31 ` Richard Kuo
2011-08-31 5:48 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110817163521.637768691@codeaurora.org \
--to=rkuo@codeaurora.org \
--cc=linux-hexagon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.