linux/arch/x86/include/asm/ptrace.h
<<
>>
Prefs
   1#ifndef _ASM_X86_PTRACE_H
   2#define _ASM_X86_PTRACE_H
   3
   4#include <asm/segment.h>
   5#include <asm/page_types.h>
   6#include <uapi/asm/ptrace.h>
   7
   8#ifndef __ASSEMBLY__
   9#ifdef __i386__
  10
  11struct pt_regs {
  12        unsigned long bx;
  13        unsigned long cx;
  14        unsigned long dx;
  15        unsigned long si;
  16        unsigned long di;
  17        unsigned long bp;
  18        unsigned long ax;
  19        unsigned long ds;
  20        unsigned long es;
  21        unsigned long fs;
  22        unsigned long gs;
  23        unsigned long orig_ax;
  24        unsigned long ip;
  25        unsigned long cs;
  26        unsigned long flags;
  27        unsigned long sp;
  28        unsigned long ss;
  29};
  30
  31#else /* __i386__ */
  32
  33struct pt_regs {
  34        unsigned long r15;
  35        unsigned long r14;
  36        unsigned long r13;
  37        unsigned long r12;
  38        unsigned long bp;
  39        unsigned long bx;
  40/* arguments: non interrupts/non tracing syscalls only save up to here*/
  41        unsigned long r11;
  42        unsigned long r10;
  43        unsigned long r9;
  44        unsigned long r8;
  45        unsigned long ax;
  46        unsigned long cx;
  47        unsigned long dx;
  48        unsigned long si;
  49        unsigned long di;
  50        unsigned long orig_ax;
  51/* end of arguments */
  52/* cpu exception frame or undefined */
  53        unsigned long ip;
  54        unsigned long cs;
  55        unsigned long flags;
  56        unsigned long sp;
  57        unsigned long ss;
  58/* top of stack page */
  59};
  60
  61#endif /* !__i386__ */
  62
  63#include <linux/init.h>
  64#ifdef CONFIG_PARAVIRT
  65#include <asm/paravirt_types.h>
  66#endif
  67
  68struct cpuinfo_x86;
  69struct task_struct;
  70
  71extern unsigned long profile_pc(struct pt_regs *regs);
  72#define profile_pc profile_pc
  73
  74extern unsigned long
  75convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
  76extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
  77                         int error_code, int si_code);
  78
  79extern long syscall_trace_enter(struct pt_regs *);
  80extern void syscall_trace_leave(struct pt_regs *);
  81
  82static inline unsigned long regs_return_value(struct pt_regs *regs)
  83{
  84        return regs->ax;
  85}
  86
  87/*
  88 * user_mode_vm(regs) determines whether a register set came from user mode.
  89 * This is true if V8086 mode was enabled OR if the register set was from
  90 * protected mode with RPL-3 CS value.  This tricky test checks that with
  91 * one comparison.  Many places in the kernel can bypass this full check
  92 * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
  93 */
  94static inline int user_mode(struct pt_regs *regs)
  95{
  96#ifdef CONFIG_X86_32
  97        return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
  98#else
  99        return !!(regs->cs & 3);
 100#endif
 101}
 102
 103static inline int user_mode_vm(struct pt_regs *regs)
 104{
 105#ifdef CONFIG_X86_32
 106        return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
 107                USER_RPL;
 108#else
 109        return user_mode(regs);
 110#endif
 111}
 112
 113static inline int v8086_mode(struct pt_regs *regs)
 114{
 115#ifdef CONFIG_X86_32
 116        return (regs->flags & X86_VM_MASK);
 117#else
 118        return 0;       /* No V86 mode support in long mode */
 119#endif
 120}
 121
 122#ifdef CONFIG_X86_64
 123static inline bool user_64bit_mode(struct pt_regs *regs)
 124{
 125#ifndef CONFIG_PARAVIRT
 126        /*
 127         * On non-paravirt systems, this is the only long mode CPL 3
 128         * selector.  We do not allow long mode selectors in the LDT.
 129         */
 130        return regs->cs == __USER_CS;
 131#else
 132        /* Headers are too twisted for this to go in paravirt.h. */
 133        return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs;
 134#endif
 135}
 136
 137#define current_user_stack_pointer()    this_cpu_read(old_rsp)
 138/* ia32 vs. x32 difference */
 139#define compat_user_stack_pointer()     \
 140        (test_thread_flag(TIF_IA32)     \
 141         ? current_pt_regs()->sp        \
 142         : this_cpu_read(old_rsp))
 143#endif
 144
 145#ifdef CONFIG_X86_32
 146extern unsigned long kernel_stack_pointer(struct pt_regs *regs);
 147#else
 148static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
 149{
 150        return regs->sp;
 151}
 152#endif
 153
 154#define GET_IP(regs) ((regs)->ip)
 155#define GET_FP(regs) ((regs)->bp)
 156#define GET_USP(regs) ((regs)->sp)
 157
 158#include <asm-generic/ptrace.h>
 159
 160/* Query offset/name of register from its name/offset */
 161extern int regs_query_register_offset(const char *name);
 162extern const char *regs_query_register_name(unsigned int offset);
 163#define MAX_REG_OFFSET (offsetof(struct pt_regs, ss))
 164
 165/**
 166 * regs_get_register() - get register value from its offset
 167 * @regs:       pt_regs from which register value is gotten.
 168 * @offset:     offset number of the register.
 169 *
 170 * regs_get_register returns the value of a register. The @offset is the
 171 * offset of the register in struct pt_regs address which specified by @regs.
 172 * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
 173 */
 174static inline unsigned long regs_get_register(struct pt_regs *regs,
 175                                              unsigned int offset)
 176{
 177        if (unlikely(offset > MAX_REG_OFFSET))
 178                return 0;
 179#ifdef CONFIG_X86_32
 180        /*
 181         * Traps from the kernel do not save sp and ss.
 182         * Use the helper function to retrieve sp.
 183         */
 184        if (offset == offsetof(struct pt_regs, sp) &&
 185            regs->cs == __KERNEL_CS)
 186                return kernel_stack_pointer(regs);
 187#endif
 188        return *(unsigned long *)((unsigned long)regs + offset);
 189}
 190
 191/**
 192 * regs_within_kernel_stack() - check the address in the stack
 193 * @regs:       pt_regs which contains kernel stack pointer.
 194 * @addr:       address which is checked.
 195 *
 196 * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
 197 * If @addr is within the kernel stack, it returns true. If not, returns false.
 198 */
 199static inline int regs_within_kernel_stack(struct pt_regs *regs,
 200                                           unsigned long addr)
 201{
 202        return ((addr & ~(THREAD_SIZE - 1))  ==
 203                (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
 204}
 205
 206/**
 207 * regs_get_kernel_stack_nth() - get Nth entry of the stack
 208 * @regs:       pt_regs which contains kernel stack pointer.
 209 * @n:          stack entry number.
 210 *
 211 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
 212 * is specified by @regs. If the @n th entry is NOT in the kernel stack,
 213 * this returns 0.
 214 */
 215static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
 216                                                      unsigned int n)
 217{
 218        unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
 219        addr += n;
 220        if (regs_within_kernel_stack(regs, (unsigned long)addr))
 221                return *addr;
 222        else
 223                return 0;
 224}
 225
 226#define arch_has_single_step()  (1)
 227#ifdef CONFIG_X86_DEBUGCTLMSR
 228#define arch_has_block_step()   (1)
 229#else
 230#define arch_has_block_step()   (boot_cpu_data.x86 >= 6)
 231#endif
 232
 233#define ARCH_HAS_USER_SINGLE_STEP_INFO
 234
 235struct user_desc;
 236extern int do_get_thread_area(struct task_struct *p, int idx,
 237                              struct user_desc __user *info);
 238extern int do_set_thread_area(struct task_struct *p, int idx,
 239                              struct user_desc __user *info, int can_allocate);
 240
 241#endif /* !__ASSEMBLY__ */
 242#endif /* _ASM_X86_PTRACE_H */
 243