sh: Add kprobe-based event tracer.

This follows the x86/ppc changes for kprobe-based event tracing on sh.
While kprobes is only supported on 32-bit sh, we provide the API for
HAVE_REGS_AND_STACK_ACCESS_API for both 32 and 64-bit.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index e25f3c6..1086ba1 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -14,7 +14,7 @@
 obj-y	:= clkdev.o debugtraps.o dma-nommu.o dumpstack.o 		\
 	   idle.o io.o irq.o						\
 	   irq_$(BITS).o machvec.o nmi_debug.o process.o		\
-	   process_$(BITS).o ptrace_$(BITS).o				\
+	   process_$(BITS).o ptrace.o ptrace_$(BITS).o			\
 	   reboot.o return_address.o					\
 	   setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o		\
 	   syscalls_$(BITS).o time.o topology.o traps.o			\
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
new file mode 100644
index 0000000..0a05983
--- /dev/null
+++ b/arch/sh/kernel/ptrace.c
@@ -0,0 +1,33 @@
+#include <linux/ptrace.h>
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name:	the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+	const struct pt_regs_offset *roff;
+	for (roff = regoffset_table; roff->name != NULL; roff++)
+		if (!strcmp(roff->name, name))
+			return roff->offset;
+	return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset:	the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+	const struct pt_regs_offset *roff;
+	for (roff = regoffset_table; roff->name != NULL; roff++)
+		if (roff->offset == offset)
+			return roff->name;
+	return NULL;
+}
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 6c4bbba..2cd42b5 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -274,6 +274,33 @@
 }
 #endif
 
+const struct pt_regs_offset regoffset_table[] = {
+	REGS_OFFSET_NAME(0),
+	REGS_OFFSET_NAME(1),
+	REGS_OFFSET_NAME(2),
+	REGS_OFFSET_NAME(3),
+	REGS_OFFSET_NAME(4),
+	REGS_OFFSET_NAME(5),
+	REGS_OFFSET_NAME(6),
+	REGS_OFFSET_NAME(7),
+	REGS_OFFSET_NAME(8),
+	REGS_OFFSET_NAME(9),
+	REGS_OFFSET_NAME(10),
+	REGS_OFFSET_NAME(11),
+	REGS_OFFSET_NAME(12),
+	REGS_OFFSET_NAME(13),
+	REGS_OFFSET_NAME(14),
+	REGS_OFFSET_NAME(15),
+	REG_OFFSET_NAME(pc),
+	REG_OFFSET_NAME(pr),
+	REG_OFFSET_NAME(sr),
+	REG_OFFSET_NAME(gbr),
+	REG_OFFSET_NAME(mach),
+	REG_OFFSET_NAME(macl),
+	REG_OFFSET_NAME(tra),
+	REG_OFFSET_END,
+};
+
 /*
  * These are our native regset flavours.
  */
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 5fd644d..b978170 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -252,6 +252,85 @@
 }
 #endif
 
+const struct pt_regs_offset regoffset_table[] = {
+	REG_OFFSET_NAME(pc),
+	REG_OFFSET_NAME(sr),
+	REG_OFFSET_NAME(syscall_nr),
+	REGS_OFFSET_NAME(0),
+	REGS_OFFSET_NAME(1),
+	REGS_OFFSET_NAME(2),
+	REGS_OFFSET_NAME(3),
+	REGS_OFFSET_NAME(4),
+	REGS_OFFSET_NAME(5),
+	REGS_OFFSET_NAME(6),
+	REGS_OFFSET_NAME(7),
+	REGS_OFFSET_NAME(8),
+	REGS_OFFSET_NAME(9),
+	REGS_OFFSET_NAME(10),
+	REGS_OFFSET_NAME(11),
+	REGS_OFFSET_NAME(12),
+	REGS_OFFSET_NAME(13),
+	REGS_OFFSET_NAME(14),
+	REGS_OFFSET_NAME(15),
+	REGS_OFFSET_NAME(16),
+	REGS_OFFSET_NAME(17),
+	REGS_OFFSET_NAME(18),
+	REGS_OFFSET_NAME(19),
+	REGS_OFFSET_NAME(20),
+	REGS_OFFSET_NAME(21),
+	REGS_OFFSET_NAME(22),
+	REGS_OFFSET_NAME(23),
+	REGS_OFFSET_NAME(24),
+	REGS_OFFSET_NAME(25),
+	REGS_OFFSET_NAME(26),
+	REGS_OFFSET_NAME(27),
+	REGS_OFFSET_NAME(28),
+	REGS_OFFSET_NAME(29),
+	REGS_OFFSET_NAME(30),
+	REGS_OFFSET_NAME(31),
+	REGS_OFFSET_NAME(32),
+	REGS_OFFSET_NAME(33),
+	REGS_OFFSET_NAME(34),
+	REGS_OFFSET_NAME(35),
+	REGS_OFFSET_NAME(36),
+	REGS_OFFSET_NAME(37),
+	REGS_OFFSET_NAME(38),
+	REGS_OFFSET_NAME(39),
+	REGS_OFFSET_NAME(40),
+	REGS_OFFSET_NAME(41),
+	REGS_OFFSET_NAME(42),
+	REGS_OFFSET_NAME(43),
+	REGS_OFFSET_NAME(44),
+	REGS_OFFSET_NAME(45),
+	REGS_OFFSET_NAME(46),
+	REGS_OFFSET_NAME(47),
+	REGS_OFFSET_NAME(48),
+	REGS_OFFSET_NAME(49),
+	REGS_OFFSET_NAME(50),
+	REGS_OFFSET_NAME(51),
+	REGS_OFFSET_NAME(52),
+	REGS_OFFSET_NAME(53),
+	REGS_OFFSET_NAME(54),
+	REGS_OFFSET_NAME(55),
+	REGS_OFFSET_NAME(56),
+	REGS_OFFSET_NAME(57),
+	REGS_OFFSET_NAME(58),
+	REGS_OFFSET_NAME(59),
+	REGS_OFFSET_NAME(60),
+	REGS_OFFSET_NAME(61),
+	REGS_OFFSET_NAME(62),
+	REGS_OFFSET_NAME(63),
+	TREGS_OFFSET_NAME(0),
+	TREGS_OFFSET_NAME(1),
+	TREGS_OFFSET_NAME(2),
+	TREGS_OFFSET_NAME(3),
+	TREGS_OFFSET_NAME(4),
+	TREGS_OFFSET_NAME(5),
+	TREGS_OFFSET_NAME(6),
+	TREGS_OFFSET_NAME(7),
+	REG_OFFSET_END,
+};
+
 /*
  * These are our native regset flavours.
  */