mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
4.2 KiB
162 lines
4.2 KiB
/* SPDX-License-Identifier: GPL-2.0 */ |
|
#ifndef __SPARC_PTRACE_H |
|
#define __SPARC_PTRACE_H |
|
|
|
#include <uapi/asm/ptrace.h> |
|
|
|
#if defined(__sparc__) && defined(__arch64__) |
|
#ifndef __ASSEMBLY__ |
|
|
|
#include <linux/compiler.h> |
|
#include <linux/threads.h> |
|
#include <asm/switch_to.h> |
|
|
|
static inline int pt_regs_trap_type(struct pt_regs *regs) |
|
{ |
|
return regs->magic & 0x1ff; |
|
} |
|
|
|
static inline bool pt_regs_is_syscall(struct pt_regs *regs) |
|
{ |
|
return (regs->tstate & TSTATE_SYSCALL); |
|
} |
|
|
|
static inline bool pt_regs_clear_syscall(struct pt_regs *regs) |
|
{ |
|
return (regs->tstate &= ~TSTATE_SYSCALL); |
|
} |
|
|
|
#define arch_ptrace_stop_needed(exit_code, info) \ |
|
({ flush_user_windows(); \ |
|
get_thread_wsaved() != 0; \ |
|
}) |
|
|
|
#define arch_ptrace_stop(exit_code, info) \ |
|
synchronize_user_stack() |
|
|
|
#define current_pt_regs() \ |
|
((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1) |
|
|
|
struct global_reg_snapshot { |
|
unsigned long tstate; |
|
unsigned long tpc; |
|
unsigned long tnpc; |
|
unsigned long o7; |
|
unsigned long i7; |
|
unsigned long rpc; |
|
struct thread_info *thread; |
|
unsigned long pad1; |
|
}; |
|
|
|
struct global_pmu_snapshot { |
|
unsigned long pcr[4]; |
|
unsigned long pic[4]; |
|
}; |
|
|
|
union global_cpu_snapshot { |
|
struct global_reg_snapshot reg; |
|
struct global_pmu_snapshot pmu; |
|
}; |
|
|
|
extern union global_cpu_snapshot global_cpu_snapshot[NR_CPUS]; |
|
|
|
#define force_successful_syscall_return() set_thread_noerror(1) |
|
#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) |
|
#define instruction_pointer(regs) ((regs)->tpc) |
|
#define instruction_pointer_set(regs, val) do { \ |
|
(regs)->tpc = (val); \ |
|
(regs)->tnpc = (val)+4; \ |
|
} while (0) |
|
#define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP]) |
|
static inline int is_syscall_success(struct pt_regs *regs) |
|
{ |
|
return !(regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)); |
|
} |
|
|
|
static inline long regs_return_value(struct pt_regs *regs) |
|
{ |
|
return regs->u_regs[UREG_I0]; |
|
} |
|
#ifdef CONFIG_SMP |
|
unsigned long profile_pc(struct pt_regs *); |
|
#else |
|
#define profile_pc(regs) instruction_pointer(regs) |
|
#endif |
|
|
|
#define MAX_REG_OFFSET (offsetof(struct pt_regs, magic)) |
|
|
|
int regs_query_register_offset(const char *name); |
|
unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n); |
|
|
|
/** |
|
* regs_get_register() - get register value from its offset |
|
* @regs: pt_regs from which register value is gotten |
|
* @offset: offset number of the register. |
|
* |
|
* regs_get_register returns the value of a register whose |
|
* offset from @regs. The @offset is the offset of the register |
|
* in struct pt_regs. If @offset is bigger than MAX_REG_OFFSET, |
|
* this returns 0. |
|
*/ |
|
static inline unsigned long regs_get_register(struct pt_regs *regs, |
|
unsigned long offset) |
|
{ |
|
if (unlikely(offset >= MAX_REG_OFFSET)) |
|
return 0; |
|
if (offset == PT_V9_Y) |
|
return *(unsigned int *)((unsigned long)regs + offset); |
|
return *(unsigned long *)((unsigned long)regs + offset); |
|
} |
|
|
|
/* Valid only for Kernel mode traps. */ |
|
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) |
|
{ |
|
return regs->u_regs[UREG_I6]; |
|
} |
|
#else /* __ASSEMBLY__ */ |
|
#endif /* __ASSEMBLY__ */ |
|
#else /* (defined(__sparc__) && defined(__arch64__)) */ |
|
#ifndef __ASSEMBLY__ |
|
#include <asm/switch_to.h> |
|
|
|
static inline bool pt_regs_is_syscall(struct pt_regs *regs) |
|
{ |
|
return (regs->psr & PSR_SYSCALL); |
|
} |
|
|
|
static inline bool pt_regs_clear_syscall(struct pt_regs *regs) |
|
{ |
|
return (regs->psr &= ~PSR_SYSCALL); |
|
} |
|
|
|
#define arch_ptrace_stop_needed(exit_code, info) \ |
|
({ flush_user_windows(); \ |
|
current_thread_info()->w_saved != 0; \ |
|
}) |
|
|
|
#define arch_ptrace_stop(exit_code, info) \ |
|
synchronize_user_stack() |
|
|
|
#define current_pt_regs() \ |
|
((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1) |
|
|
|
#define user_mode(regs) (!((regs)->psr & PSR_PS)) |
|
#define instruction_pointer(regs) ((regs)->pc) |
|
#define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP]) |
|
unsigned long profile_pc(struct pt_regs *); |
|
#else /* (!__ASSEMBLY__) */ |
|
#endif /* (!__ASSEMBLY__) */ |
|
#endif /* (defined(__sparc__) && defined(__arch64__)) */ |
|
#define STACK_BIAS 2047 |
|
|
|
/* global_reg_snapshot offsets */ |
|
#define GR_SNAP_TSTATE 0x00 |
|
#define GR_SNAP_TPC 0x08 |
|
#define GR_SNAP_TNPC 0x10 |
|
#define GR_SNAP_O7 0x18 |
|
#define GR_SNAP_I7 0x20 |
|
#define GR_SNAP_RPC 0x28 |
|
#define GR_SNAP_THREAD 0x30 |
|
#define GR_SNAP_PAD1 0x38 |
|
|
|
#endif /* !(__SPARC_PTRACE_H) */
|
|
|