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/*
  35 * C ABI says these regs are callee-preserved. They aren't saved on kernel entry
  36 * unless syscall needs a complete, fully filled "struct pt_regs".
  37 */
  38        unsigned long r15;
  39        unsigned long r14;
  40        unsigned long r13;
  41        unsigned long r12;
  42        unsigned long bp;
  43        unsigned long bx;
  44/* These regs are callee-clobbered. Always saved on kernel entry. */
  45        unsigned long r11;
  46        unsigned long r10;
  47        unsigned long r9;
  48        unsigned long r8;
  49        unsigned long ax;
  50        unsigned long cx;
  51        unsigned long dx;
  52        unsigned long si;
  53        unsigned long di;
  54/*
  55 * On syscall entry, this is syscall#. On CPU exception, this is error code.
  56 * On hw interrupt, it's IRQ number:
  57 */
  58        unsigned long orig_ax;
  59/* Return frame for iretq */
  60        unsigned long ip;
  61        unsigned long cs;
  62        unsigned long flags;
  63        unsigned long sp;
  64        unsigned long ss;
  65/* top of stack page */
  66};
  67
  68#endif /* !__i386__ */
  69
  70#ifdef CONFIG_PARAVIRT
  71#include <asm/paravirt_types.h>
  72#endif
  73
  74struct cpuinfo_x86;
  75struct task_struct;
  76
  77extern unsigned long profile_pc(struct pt_regs *regs);
  78#define profile_pc profile_pc
  79
  80extern unsigned long
  81convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
  82extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
  83                         int error_code, int si_code);
  84
  85
  86static inline unsigned long regs_return_value(struct pt_regs *regs)
  87{
  88        return regs->ax;
  89}
  90
  91/*
  92 * user_mode(regs) determines whether a register set came from user
  93 * mode.  On x86_32, this is true if V8086 mode was enabled OR if the
  94 * register set was from protected mode with RPL-3 CS value.  This
  95 * tricky test checks that with one comparison.
  96 *
  97 * On x86_64, vm86 mode is mercifully nonexistent, and we don't need
  98 * the extra check.
  99 */
 100static inline int user_mode(struct pt_regs *regs)
 101{
 102#ifdef CONFIG_X86_32
 103        return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL;
 104#else
 105        return !!(regs->cs & 3);
 106#endif
 107}
 108
 109static inline int v8086_mode(struct pt_regs *regs)
 110{
 111#ifdef CONFIG_X86_32
 112        return (regs->flags & X86_VM_MASK);
 113#else
 114        return 0;       /* No V86 mode support in long mode */
 115#endif
 116}
 117
 118#ifdef CONFIG_X86_64
 119static inline bool user_64bit_mode(struct pt_regs *regs)
 120{
 121#ifndef CONFIG_PARAVIRT
 122        /*
 123         * On non-paravirt systems, this is the only long mode CPL 3
 124         * selector.  We do not allow long mode selectors in the LDT.
 125         */
 126        return regs->cs == __USER_CS;
 127#else
 128        /* Headers are too twisted for this to go in paravirt.h. */
 129        return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs;
 130#endif
 131}
 132
 133#define current_user_stack_pointer()    current_pt_regs()->sp
 134#define compat_user_stack_pointer()     current_pt_regs()->sp
 135#endif
 136
 137#ifdef CONFIG_X86_32
 138extern unsigned long kernel_stack_pointer(struct pt_regs *regs);
 139#else
 140static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
 141{
 142        return regs->sp;
 143}
 144#endif
 145
 146#define GET_IP(regs) ((regs)->ip)
 147#define GET_FP(regs) ((regs)->bp)
 148#define GET_USP(regs) ((regs)->sp)
 149
 150#include <asm-generic/ptrace.h>
 151
 152/* Query offset/name of register from its name/offset */
 153extern int regs_query_register_offset(const char *name);
 154extern const char *regs_query_register_name(unsigned int offset);
 155#define MAX_REG_OFFSET (offsetof(struct pt_regs, ss))
 156
 157/**
 158 * regs_get_register() - get register value from its offset
 159 * @regs:       pt_regs from which register value is gotten.
 160 * @offset:     offset number of the register.
 161 *
 162 * regs_get_register returns the value of a register. The @offset is the
 163 * offset of the register in struct pt_regs address which specified by @regs.
 164 * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
 165 */
 166static inline unsigned long regs_get_register(struct pt_regs *regs,
 167                                              unsigned int offset)
 168{
 169        if (unlikely(offset > MAX_REG_OFFSET))
 170                return 0;
 171#ifdef CONFIG_X86_32
 172        /*
 173         * Traps from the kernel do not save sp and ss.
 174         * Use the helper function to retrieve sp.
 175         */
 176        if (offset == offsetof(struct pt_regs, sp) &&
 177            regs->cs == __KERNEL_CS)
 178                return kernel_stack_pointer(regs);
 179#endif
 180        return *(unsigned long *)((unsigned long)regs + offset);
 181}
 182
 183/**
 184 * regs_within_kernel_stack() - check the address in the stack
 185 * @regs:       pt_regs which contains kernel stack pointer.
 186 * @addr:       address which is checked.
 187 *
 188 * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
 189 * If @addr is within the kernel stack, it returns true. If not, returns false.
 190 */
 191static inline int regs_within_kernel_stack(struct pt_regs *regs,
 192                                           unsigned long addr)
 193{
 194        return ((addr & ~(THREAD_SIZE - 1))  ==
 195                (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
 196}
 197
 198/**
 199 * regs_get_kernel_stack_nth() - get Nth entry of the stack
 200 * @regs:       pt_regs which contains kernel stack pointer.
 201 * @n:          stack entry number.
 202 *
 203 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
 204 * is specified by @regs. If the @n th entry is NOT in the kernel stack,
 205 * this returns 0.
 206 */
 207static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
 208                                                      unsigned int n)
 209{
 210        unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
 211        addr += n;
 212        if (regs_within_kernel_stack(regs, (unsigned long)addr))
 213                return *addr;
 214        else
 215                return 0;
 216}
 217
 218#define arch_has_single_step()  (1)
 219#ifdef CONFIG_X86_DEBUGCTLMSR
 220#define arch_has_block_step()   (1)
 221#else
 222#define arch_has_block_step()   (boot_cpu_data.x86 >= 6)
 223#endif
 224
 225#define ARCH_HAS_USER_SINGLE_STEP_INFO
 226
 227/*
 228 * When hitting ptrace_stop(), we cannot return using SYSRET because
 229 * that does not restore the full CPU state, only a minimal set.  The
 230 * ptracer can change arbitrary register values, which is usually okay
 231 * because the usual ptrace stops run off the signal delivery path which
 232 * forces IRET; however, ptrace_event() stops happen in arbitrary places
 233 * in the kernel and don't force IRET path.
 234 *
 235 * So force IRET path after a ptrace stop.
 236 */
 237#define arch_ptrace_stop_needed(code, info)                             \
 238({                                                                      \
 239        force_iret();                                                   \
 240        false;                                                          \
 241})
 242
 243struct user_desc;
 244extern int do_get_thread_area(struct task_struct *p, int idx,
 245                              struct user_desc __user *info);
 246extern int do_set_thread_area(struct task_struct *p, int idx,
 247                              struct user_desc __user *info, int can_allocate);
 248
 249#endif /* !__ASSEMBLY__ */
 250#endif /* _ASM_X86_PTRACE_H */
 251