11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999, 2000 Niibe Yutaka 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 40a9426df1858f71ac84eb7eef500b4247de5e3bbDavid Howells#ifndef __ASM_SH_PTRACE_H 50a9426df1858f71ac84eb7eef500b4247de5e3bbDavid Howells#define __ASM_SH_PTRACE_H 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7da28c597996a964a195529595c37f7aacd6dad09Paul Mundt 8da28c597996a964a195529595c37f7aacd6dad09Paul Mundt#include <linux/stringify.h> 9da28c597996a964a195529595c37f7aacd6dad09Paul Mundt#include <linux/stddef.h> 10da28c597996a964a195529595c37f7aacd6dad09Paul Mundt#include <linux/thread_info.h> 1133f242ed11ce6b5fbe73fe4ece7ef4bc2f4e2851Paul Mundt#include <asm/addrspace.h> 12b0f3ae03aca0f331b851ae94bc066124e7f104dfPaul Mundt#include <asm/page.h> 130a9426df1858f71ac84eb7eef500b4247de5e3bbDavid Howells#include <uapi/asm/ptrace.h> 1433f242ed11ce6b5fbe73fe4ece7ef4bc2f4e2851Paul Mundt 1533f242ed11ce6b5fbe73fe4ece7ef4bc2f4e2851Paul Mundt#define user_mode(regs) (((regs)->sr & 0x40000000)==0) 16eac676e531214f1e276645613acae7d7c4529035Roel Kluin#define kernel_stack_pointer(_regs) ((unsigned long)(_regs)->regs[15]) 17db7eba292e913390fa881272bfbc3da0a5380513Paul Mundt 18db7eba292e913390fa881272bfbc3da0a5380513Paul Mundt#define GET_FP(regs) ((regs)->regs[14]) 19db7eba292e913390fa881272bfbc3da0a5380513Paul Mundt#define GET_USP(regs) ((regs)->regs[15]) 2033f242ed11ce6b5fbe73fe4ece7ef4bc2f4e2851Paul Mundt 21eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt#define arch_has_single_step() (1) 22eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt 23c459dbf294b4a3d70490a468a7ca3907fb2c2f57Paul Mundt/* 24eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * kprobe-based event tracer support 25c459dbf294b4a3d70490a468a7ca3907fb2c2f57Paul Mundt */ 26eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtstruct pt_regs_offset { 27eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt const char *name; 28eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt int offset; 29eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt}; 30eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt 31eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)} 32eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt#define REGS_OFFSET_NAME(num) \ 33eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt {.name = __stringify(r##num), .offset = offsetof(struct pt_regs, regs[num])} 34da28c597996a964a195529595c37f7aacd6dad09Paul Mundt#define TREGS_OFFSET_NAME(num) \ 35da28c597996a964a195529595c37f7aacd6dad09Paul Mundt {.name = __stringify(tr##num), .offset = offsetof(struct pt_regs, tregs[num])} 36eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt#define REG_OFFSET_END {.name = NULL, .offset = 0} 37eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt 38eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt/* Query offset/name of register from its name/offset */ 39eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtextern int regs_query_register_offset(const char *name); 40eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtextern const char *regs_query_register_name(unsigned int offset); 41eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt 42eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtextern const struct pt_regs_offset regoffset_table[]; 43eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt 44eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt/** 45eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_get_register() - get register value from its offset 46eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @regs: pt_regs from which register value is gotten. 47eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @offset: offset number of the register. 48eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * 49eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_get_register returns the value of a register. The @offset is the 50eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * offset of the register in struct pt_regs address which specified by @regs. 51eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * If @offset is bigger than MAX_REG_OFFSET, this returns 0. 52eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt */ 53eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtstatic inline unsigned long regs_get_register(struct pt_regs *regs, 54eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt unsigned int offset) 55eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt{ 56eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt if (unlikely(offset > MAX_REG_OFFSET)) 57eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt return 0; 58eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt return *(unsigned long *)((unsigned long)regs + offset); 59eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt} 60eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt 61eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt/** 62eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_within_kernel_stack() - check the address in the stack 63eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @regs: pt_regs which contains kernel stack pointer. 64eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @addr: address which is checked. 65eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * 66eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). 67eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * If @addr is within the kernel stack, it returns true. If not, returns false. 68eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt */ 69eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtstatic inline int regs_within_kernel_stack(struct pt_regs *regs, 70eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt unsigned long addr) 71eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt{ 72eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt return ((addr & ~(THREAD_SIZE - 1)) == 73eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))); 74eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt} 75eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt 76eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt/** 77eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_get_kernel_stack_nth() - get Nth entry of the stack 78eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @regs: pt_regs which contains kernel stack pointer. 79eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * @n: stack entry number. 80eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * 81eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which 82eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * is specified by @regs. If the @n th entry is NOT in the kernel stack, 83eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt * this returns 0. 84eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt */ 85eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundtstatic inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, 86eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt unsigned int n) 87eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt{ 88eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); 89eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt addr += n; 90eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt if (regs_within_kernel_stack(regs, (unsigned long)addr)) 91eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt return *addr; 92eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt else 93eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt return 0; 94eaaaeef392cb245e415c31d480ed2d5a466fd88fPaul Mundt} 95c459dbf294b4a3d70490a468a7ca3907fb2c2f57Paul Mundt 9634d0b5af50a063cded842716633501b38ff815fbPaul Mundtstruct perf_event; 9734d0b5af50a063cded842716633501b38ff815fbPaul Mundtstruct perf_sample_data; 9834d0b5af50a063cded842716633501b38ff815fbPaul Mundt 99c84b51e65ea2f256353c339bd87e991b7e64630fPaul Gortmakerextern void ptrace_triggered(struct perf_event *bp, 10034d0b5af50a063cded842716633501b38ff815fbPaul Mundt struct perf_sample_data *data, struct pt_regs *regs); 10134d0b5af50a063cded842716633501b38ff815fbPaul Mundt 1023cf0f4ece9f1680e54b154b1e38baaf6ace20a62Al Viro#define task_pt_regs(task) \ 1034f099ebb27211d378304ddcfa507097f5128f5b9Magnus Damm ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1) 1043cf0f4ece9f1680e54b154b1e38baaf6ace20a62Al Viro 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned long profile_pc(struct pt_regs *regs) 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 107db7eba292e913390fa881272bfbc3da0a5380513Paul Mundt unsigned long pc = regs->pc; 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1099edef28653a519bf0a48250f36cce96b1736ec4ePaul Mundt if (virt_addr_uncached(pc)) 1109edef28653a519bf0a48250f36cce96b1736ec4ePaul Mundt return CAC_ADDR(pc); 11133f242ed11ce6b5fbe73fe4ece7ef4bc2f4e2851Paul Mundt 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pc; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1143cea45c6ef459b776123a4855eba6dafd506f3ceMike Frysinger#define profile_pc profile_pc 1153cea45c6ef459b776123a4855eba6dafd506f3ceMike Frysinger 1163cea45c6ef459b776123a4855eba6dafd506f3ceMike Frysinger#include <asm-generic/ptrace.h> 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __ASM_SH_PTRACE_H */ 118