250 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#ifndef _ASM_X86_PTRACE_H
 | 
						|
#define _ASM_X86_PTRACE_H
 | 
						|
 | 
						|
#include <linux/compiler.h>	/* For __user */
 | 
						|
#include <asm/ptrace-abi.h>
 | 
						|
#include <asm/processor-flags.h>
 | 
						|
 | 
						|
#ifdef __KERNEL__
 | 
						|
#include <asm/segment.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef __ASSEMBLY__
 | 
						|
 | 
						|
#ifdef __i386__
 | 
						|
/* this struct defines the way the registers are stored on the
 | 
						|
   stack during a system call. */
 | 
						|
 | 
						|
#ifndef __KERNEL__
 | 
						|
 | 
						|
struct pt_regs {
 | 
						|
	long ebx;
 | 
						|
	long ecx;
 | 
						|
	long edx;
 | 
						|
	long esi;
 | 
						|
	long edi;
 | 
						|
	long ebp;
 | 
						|
	long eax;
 | 
						|
	int  xds;
 | 
						|
	int  xes;
 | 
						|
	int  xfs;
 | 
						|
	int  xgs;
 | 
						|
	long orig_eax;
 | 
						|
	long eip;
 | 
						|
	int  xcs;
 | 
						|
	long eflags;
 | 
						|
	long esp;
 | 
						|
	int  xss;
 | 
						|
};
 | 
						|
 | 
						|
#else /* __KERNEL__ */
 | 
						|
 | 
						|
struct pt_regs {
 | 
						|
	unsigned long bx;
 | 
						|
	unsigned long cx;
 | 
						|
	unsigned long dx;
 | 
						|
	unsigned long si;
 | 
						|
	unsigned long di;
 | 
						|
	unsigned long bp;
 | 
						|
	unsigned long ax;
 | 
						|
	unsigned long ds;
 | 
						|
	unsigned long es;
 | 
						|
	unsigned long fs;
 | 
						|
	unsigned long gs;
 | 
						|
	unsigned long orig_ax;
 | 
						|
	unsigned long ip;
 | 
						|
	unsigned long cs;
 | 
						|
	unsigned long flags;
 | 
						|
	unsigned long sp;
 | 
						|
	unsigned long ss;
 | 
						|
};
 | 
						|
 | 
						|
#endif /* __KERNEL__ */
 | 
						|
 | 
						|
#else /* __i386__ */
 | 
						|
 | 
						|
#ifndef __KERNEL__
 | 
						|
 | 
						|
struct pt_regs {
 | 
						|
	unsigned long r15;
 | 
						|
	unsigned long r14;
 | 
						|
	unsigned long r13;
 | 
						|
	unsigned long r12;
 | 
						|
	unsigned long rbp;
 | 
						|
	unsigned long rbx;
 | 
						|
/* arguments: non interrupts/non tracing syscalls only save upto here*/
 | 
						|
	unsigned long r11;
 | 
						|
	unsigned long r10;
 | 
						|
	unsigned long r9;
 | 
						|
	unsigned long r8;
 | 
						|
	unsigned long rax;
 | 
						|
	unsigned long rcx;
 | 
						|
	unsigned long rdx;
 | 
						|
	unsigned long rsi;
 | 
						|
	unsigned long rdi;
 | 
						|
	unsigned long orig_rax;
 | 
						|
/* end of arguments */
 | 
						|
/* cpu exception frame or undefined */
 | 
						|
	unsigned long rip;
 | 
						|
	unsigned long cs;
 | 
						|
	unsigned long eflags;
 | 
						|
	unsigned long rsp;
 | 
						|
	unsigned long ss;
 | 
						|
/* top of stack page */
 | 
						|
};
 | 
						|
 | 
						|
#else /* __KERNEL__ */
 | 
						|
 | 
						|
struct pt_regs {
 | 
						|
	unsigned long r15;
 | 
						|
	unsigned long r14;
 | 
						|
	unsigned long r13;
 | 
						|
	unsigned long r12;
 | 
						|
	unsigned long bp;
 | 
						|
	unsigned long bx;
 | 
						|
/* arguments: non interrupts/non tracing syscalls only save upto here*/
 | 
						|
	unsigned long r11;
 | 
						|
	unsigned long r10;
 | 
						|
	unsigned long r9;
 | 
						|
	unsigned long r8;
 | 
						|
	unsigned long ax;
 | 
						|
	unsigned long cx;
 | 
						|
	unsigned long dx;
 | 
						|
	unsigned long si;
 | 
						|
	unsigned long di;
 | 
						|
	unsigned long orig_ax;
 | 
						|
/* end of arguments */
 | 
						|
/* cpu exception frame or undefined */
 | 
						|
	unsigned long ip;
 | 
						|
	unsigned long cs;
 | 
						|
	unsigned long flags;
 | 
						|
	unsigned long sp;
 | 
						|
	unsigned long ss;
 | 
						|
/* top of stack page */
 | 
						|
};
 | 
						|
 | 
						|
#endif /* __KERNEL__ */
 | 
						|
#endif /* !__i386__ */
 | 
						|
 | 
						|
 | 
						|
#ifdef __KERNEL__
 | 
						|
 | 
						|
#include <linux/init.h>
 | 
						|
 | 
						|
struct cpuinfo_x86;
 | 
						|
struct task_struct;
 | 
						|
 | 
						|
extern unsigned long profile_pc(struct pt_regs *regs);
 | 
						|
 | 
						|
extern unsigned long
 | 
						|
convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
 | 
						|
extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
 | 
						|
			 int error_code, int si_code);
 | 
						|
void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
 | 
						|
 | 
						|
extern long syscall_trace_enter(struct pt_regs *);
 | 
						|
extern void syscall_trace_leave(struct pt_regs *);
 | 
						|
 | 
						|
static inline unsigned long regs_return_value(struct pt_regs *regs)
 | 
						|
{
 | 
						|
	return regs->ax;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * user_mode_vm(regs) determines whether a register set came from user mode.
 | 
						|
 * This is true if V8086 mode was enabled OR if the register set was from
 | 
						|
 * protected mode with RPL-3 CS value.  This tricky test checks that with
 | 
						|
 * one comparison.  Many places in the kernel can bypass this full check
 | 
						|
 * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
 | 
						|
 */
 | 
						|
static inline int user_mode(struct pt_regs *regs)
 | 
						|
{
 | 
						|
#ifdef CONFIG_X86_32
 | 
						|
	return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
 | 
						|
#else
 | 
						|
	return !!(regs->cs & 3);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
static inline int user_mode_vm(struct pt_regs *regs)
 | 
						|
{
 | 
						|
#ifdef CONFIG_X86_32
 | 
						|
	return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
 | 
						|
		USER_RPL;
 | 
						|
#else
 | 
						|
	return user_mode(regs);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
static inline int v8086_mode(struct pt_regs *regs)
 | 
						|
{
 | 
						|
#ifdef CONFIG_X86_32
 | 
						|
	return (regs->flags & X86_VM_MASK);
 | 
						|
#else
 | 
						|
	return 0;	/* No V86 mode support in long mode */
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
 | 
						|
 * when it traps.  The previous stack will be directly underneath the saved
 | 
						|
 * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'.
 | 
						|
 *
 | 
						|
 * This is valid only for kernel mode traps.
 | 
						|
 */
 | 
						|
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
 | 
						|
{
 | 
						|
#ifdef CONFIG_X86_32
 | 
						|
	return (unsigned long)(®s->sp);
 | 
						|
#else
 | 
						|
	return regs->sp;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
static inline unsigned long instruction_pointer(struct pt_regs *regs)
 | 
						|
{
 | 
						|
	return regs->ip;
 | 
						|
}
 | 
						|
 | 
						|
static inline unsigned long frame_pointer(struct pt_regs *regs)
 | 
						|
{
 | 
						|
	return regs->bp;
 | 
						|
}
 | 
						|
 | 
						|
static inline unsigned long user_stack_pointer(struct pt_regs *regs)
 | 
						|
{
 | 
						|
	return regs->sp;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * These are defined as per linux/ptrace.h, which see.
 | 
						|
 */
 | 
						|
#define arch_has_single_step()	(1)
 | 
						|
extern void user_enable_single_step(struct task_struct *);
 | 
						|
extern void user_disable_single_step(struct task_struct *);
 | 
						|
 | 
						|
extern void user_enable_block_step(struct task_struct *);
 | 
						|
#ifdef CONFIG_X86_DEBUGCTLMSR
 | 
						|
#define arch_has_block_step()	(1)
 | 
						|
#else
 | 
						|
#define arch_has_block_step()	(boot_cpu_data.x86 >= 6)
 | 
						|
#endif
 | 
						|
 | 
						|
struct user_desc;
 | 
						|
extern int do_get_thread_area(struct task_struct *p, int idx,
 | 
						|
			      struct user_desc __user *info);
 | 
						|
extern int do_set_thread_area(struct task_struct *p, int idx,
 | 
						|
			      struct user_desc __user *info, int can_allocate);
 | 
						|
 | 
						|
#ifdef CONFIG_X86_PTRACE_BTS
 | 
						|
extern void ptrace_bts_untrace(struct task_struct *tsk);
 | 
						|
 | 
						|
#define arch_ptrace_untrace(tsk)	ptrace_bts_untrace(tsk)
 | 
						|
#endif /* CONFIG_X86_PTRACE_BTS */
 | 
						|
 | 
						|
#endif /* __KERNEL__ */
 | 
						|
 | 
						|
#endif /* !__ASSEMBLY__ */
 | 
						|
 | 
						|
#endif /* _ASM_X86_PTRACE_H */
 |