Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef __SPARC_PTRACE_H
0003 #define __SPARC_PTRACE_H
0004 
0005 #include <uapi/asm/ptrace.h>
0006 
0007 #if defined(__sparc__) && defined(__arch64__)
0008 #ifndef __ASSEMBLY__
0009 
0010 #include <linux/compiler.h>
0011 #include <linux/threads.h>
0012 #include <asm/switch_to.h>
0013 
0014 static inline int pt_regs_trap_type(struct pt_regs *regs)
0015 {
0016     return regs->magic & 0x1ff;
0017 }
0018 
0019 static inline bool pt_regs_is_syscall(struct pt_regs *regs)
0020 {
0021     return (regs->tstate & TSTATE_SYSCALL);
0022 }
0023 
0024 static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
0025 {
0026     return (regs->tstate &= ~TSTATE_SYSCALL);
0027 }
0028 
0029 #define arch_ptrace_stop_needed() \
0030 ({  flush_user_windows(); \
0031     get_thread_wsaved() != 0; \
0032 })
0033 
0034 #define arch_ptrace_stop() \
0035     synchronize_user_stack()
0036 
0037 #define current_pt_regs() \
0038     ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
0039 
0040 struct global_reg_snapshot {
0041     unsigned long       tstate;
0042     unsigned long       tpc;
0043     unsigned long       tnpc;
0044     unsigned long       o7;
0045     unsigned long       i7;
0046     unsigned long       rpc;
0047     struct thread_info  *thread;
0048     unsigned long       pad1;
0049 };
0050 
0051 struct global_pmu_snapshot {
0052     unsigned long       pcr[4];
0053     unsigned long       pic[4];
0054 };
0055 
0056 union global_cpu_snapshot {
0057     struct global_reg_snapshot  reg;
0058     struct global_pmu_snapshot  pmu;
0059 };
0060 
0061 extern union global_cpu_snapshot global_cpu_snapshot[NR_CPUS];
0062 
0063 #define force_successful_syscall_return() set_thread_noerror(1)
0064 #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
0065 #define instruction_pointer(regs) ((regs)->tpc)
0066 #define instruction_pointer_set(regs, val) do { \
0067         (regs)->tpc = (val); \
0068         (regs)->tnpc = (val)+4; \
0069     } while (0)
0070 #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP])
0071 static inline int is_syscall_success(struct pt_regs *regs)
0072 {
0073     return !(regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY));
0074 }
0075 
0076 static inline long regs_return_value(struct pt_regs *regs)
0077 {
0078     return regs->u_regs[UREG_I0];
0079 }
0080 #ifdef CONFIG_SMP
0081 unsigned long profile_pc(struct pt_regs *);
0082 #else
0083 #define profile_pc(regs) instruction_pointer(regs)
0084 #endif
0085 
0086 #define MAX_REG_OFFSET (offsetof(struct pt_regs, magic))
0087 
0088 int regs_query_register_offset(const char *name);
0089 unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n);
0090 
0091 /**
0092  * regs_get_register() - get register value from its offset
0093  * @regs:   pt_regs from which register value is gotten
0094  * @offset: offset number of the register.
0095  *
0096  * regs_get_register returns the value of a register whose
0097  * offset from @regs. The @offset is the offset of the register
0098  * in struct pt_regs. If @offset is bigger than MAX_REG_OFFSET,
0099  * this returns 0.
0100  */
0101 static inline unsigned long regs_get_register(struct pt_regs *regs,
0102                          unsigned long offset)
0103 {
0104     if (unlikely(offset >= MAX_REG_OFFSET))
0105         return 0;
0106     if (offset == PT_V9_Y)
0107         return *(unsigned int *)((unsigned long)regs + offset);
0108     return *(unsigned long *)((unsigned long)regs + offset);
0109 }
0110 
0111 /* Valid only for Kernel mode traps. */
0112 static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
0113 {
0114     return regs->u_regs[UREG_I6];
0115 }
0116 #else /* __ASSEMBLY__ */
0117 #endif /* __ASSEMBLY__ */
0118 #else /* (defined(__sparc__) && defined(__arch64__)) */
0119 #ifndef __ASSEMBLY__
0120 #include <asm/switch_to.h>
0121 
0122 static inline bool pt_regs_is_syscall(struct pt_regs *regs)
0123 {
0124     return (regs->psr & PSR_SYSCALL);
0125 }
0126 
0127 static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
0128 {
0129     return (regs->psr &= ~PSR_SYSCALL);
0130 }
0131 
0132 #define arch_ptrace_stop_needed() \
0133 ({  flush_user_windows(); \
0134     current_thread_info()->w_saved != 0;    \
0135 })
0136 
0137 #define arch_ptrace_stop() \
0138     synchronize_user_stack()
0139 
0140 #define current_pt_regs() \
0141     ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
0142 
0143 #define user_mode(regs) (!((regs)->psr & PSR_PS))
0144 #define instruction_pointer(regs) ((regs)->pc)
0145 #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP])
0146 unsigned long profile_pc(struct pt_regs *);
0147 #else /* (!__ASSEMBLY__) */
0148 #endif /* (!__ASSEMBLY__) */
0149 #endif /* (defined(__sparc__) && defined(__arch64__)) */
0150 #define STACK_BIAS      2047
0151 
0152 /* global_reg_snapshot offsets */
0153 #define GR_SNAP_TSTATE  0x00
0154 #define GR_SNAP_TPC 0x08
0155 #define GR_SNAP_TNPC    0x10
0156 #define GR_SNAP_O7  0x18
0157 #define GR_SNAP_I7  0x20
0158 #define GR_SNAP_RPC 0x28
0159 #define GR_SNAP_THREAD  0x30
0160 #define GR_SNAP_PAD1    0x38
0161 
0162 #endif /* !(__SPARC_PTRACE_H) */