Subversion Repositories Kolibri OS

Rev

Rev 6082 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.  
  11. struct 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.  
  33. struct 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. #ifdef CONFIG_PARAVIRT
  64. #include <asm/paravirt_types.h>
  65. #endif
  66.  
  67. struct cpuinfo_x86;
  68. struct task_struct;
  69.  
  70. extern unsigned long profile_pc(struct pt_regs *regs);
  71. #define profile_pc profile_pc
  72.  
  73. extern unsigned long
  74. convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
  75. extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
  76.                          int error_code, int si_code);
  77.  
  78.  
  79. extern unsigned long syscall_trace_enter_phase1(struct pt_regs *, u32 arch);
  80. extern long syscall_trace_enter_phase2(struct pt_regs *, u32 arch,
  81.                                        unsigned long phase1_result);
  82.  
  83. extern long syscall_trace_enter(struct pt_regs *);
  84. extern void syscall_trace_leave(struct pt_regs *);
  85.  
  86. static inline unsigned long regs_return_value(struct pt_regs *regs)
  87. {
  88.         return regs->ax;
  89. }
  90.  
  91. /*
  92.  * user_mode_vm(regs) determines whether a register set came from user mode.
  93.  * This is true if V8086 mode was enabled OR if the register set was from
  94.  * protected mode with RPL-3 CS value.  This tricky test checks that with
  95.  * one comparison.  Many places in the kernel can bypass this full check
  96.  * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
  97.  */
  98. static inline int user_mode(struct pt_regs *regs)
  99. {
  100. #ifdef CONFIG_X86_32
  101.         return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
  102. #else
  103.         return !!(regs->cs & 3);
  104. #endif
  105. }
  106.  
  107. static inline int user_mode_vm(struct pt_regs *regs)
  108. {
  109. #ifdef CONFIG_X86_32
  110.         return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
  111.                 USER_RPL;
  112. #else
  113.         return user_mode(regs);
  114. #endif
  115. }
  116.  
  117. static inline int v8086_mode(struct pt_regs *regs)
  118. {
  119. #ifdef CONFIG_X86_32
  120.         return (regs->flags & X86_VM_MASK);
  121. #else
  122.         return 0;       /* No V86 mode support in long mode */
  123. #endif
  124. }
  125.  
  126. #ifdef CONFIG_X86_64
  127. static inline bool user_64bit_mode(struct pt_regs *regs)
  128. {
  129. #ifndef CONFIG_PARAVIRT
  130.         /*
  131.          * On non-paravirt systems, this is the only long mode CPL 3
  132.          * selector.  We do not allow long mode selectors in the LDT.
  133.          */
  134.         return regs->cs == __USER_CS;
  135. #else
  136.         /* Headers are too twisted for this to go in paravirt.h. */
  137.         return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs;
  138. #endif
  139. }
  140.  
  141. #define current_user_stack_pointer()    this_cpu_read(old_rsp)
  142. /* ia32 vs. x32 difference */
  143. #define compat_user_stack_pointer()     \
  144.         (test_thread_flag(TIF_IA32)     \
  145.          ? current_pt_regs()->sp        \
  146.          : this_cpu_read(old_rsp))
  147. #endif
  148.  
  149. #ifdef CONFIG_X86_32
  150. extern unsigned long kernel_stack_pointer(struct pt_regs *regs);
  151. #else
  152. static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
  153. {
  154.         return regs->sp;
  155. }
  156. #endif
  157.  
  158. #define GET_IP(regs) ((regs)->ip)
  159. #define GET_FP(regs) ((regs)->bp)
  160. #define GET_USP(regs) ((regs)->sp)
  161.  
  162. #include <asm-generic/ptrace.h>
  163.  
  164. /* Query offset/name of register from its name/offset */
  165. extern int regs_query_register_offset(const char *name);
  166. extern const char *regs_query_register_name(unsigned int offset);
  167. #define MAX_REG_OFFSET (offsetof(struct pt_regs, ss))
  168.  
  169. /**
  170.  * regs_get_register() - get register value from its offset
  171.  * @regs:       pt_regs from which register value is gotten.
  172.  * @offset:     offset number of the register.
  173.  *
  174.  * regs_get_register returns the value of a register. The @offset is the
  175.  * offset of the register in struct pt_regs address which specified by @regs.
  176.  * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
  177.  */
  178. static inline unsigned long regs_get_register(struct pt_regs *regs,
  179.                                               unsigned int offset)
  180. {
  181.         if (unlikely(offset > MAX_REG_OFFSET))
  182.                 return 0;
  183. #ifdef CONFIG_X86_32
  184.         /*
  185.          * Traps from the kernel do not save sp and ss.
  186.          * Use the helper function to retrieve sp.
  187.          */
  188.         if (offset == offsetof(struct pt_regs, sp) &&
  189.             regs->cs == __KERNEL_CS)
  190.                 return kernel_stack_pointer(regs);
  191. #endif
  192.         return *(unsigned long *)((unsigned long)regs + offset);
  193. }
  194.  
  195. /**
  196.  * regs_within_kernel_stack() - check the address in the stack
  197.  * @regs:       pt_regs which contains kernel stack pointer.
  198.  * @addr:       address which is checked.
  199.  *
  200.  * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
  201.  * If @addr is within the kernel stack, it returns true. If not, returns false.
  202.  */
  203. static inline int regs_within_kernel_stack(struct pt_regs *regs,
  204.                                            unsigned long addr)
  205. {
  206.         return ((addr & ~(THREAD_SIZE - 1))  ==
  207.                 (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
  208. }
  209.  
  210. /**
  211.  * regs_get_kernel_stack_nth() - get Nth entry of the stack
  212.  * @regs:       pt_regs which contains kernel stack pointer.
  213.  * @n:          stack entry number.
  214.  *
  215.  * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
  216.  * is specified by @regs. If the @n th entry is NOT in the kernel stack,
  217.  * this returns 0.
  218.  */
  219. static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
  220.                                                       unsigned int n)
  221. {
  222.         unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
  223.         addr += n;
  224.         if (regs_within_kernel_stack(regs, (unsigned long)addr))
  225.                 return *addr;
  226.         else
  227.                 return 0;
  228. }
  229.  
  230. #define arch_has_single_step()  (1)
  231. #ifdef CONFIG_X86_DEBUGCTLMSR
  232. #define arch_has_block_step()   (1)
  233. #else
  234. #define arch_has_block_step()   (boot_cpu_data.x86 >= 6)
  235. #endif
  236.  
  237. #define ARCH_HAS_USER_SINGLE_STEP_INFO
  238.  
  239. /*
  240.  * When hitting ptrace_stop(), we cannot return using SYSRET because
  241.  * that does not restore the full CPU state, only a minimal set.  The
  242.  * ptracer can change arbitrary register values, which is usually okay
  243.  * because the usual ptrace stops run off the signal delivery path which
  244.  * forces IRET; however, ptrace_event() stops happen in arbitrary places
  245.  * in the kernel and don't force IRET path.
  246.  *
  247.  * So force IRET path after a ptrace stop.
  248.  */
  249. #define arch_ptrace_stop_needed(code, info)                             \
  250. ({                                                                      \
  251.         set_thread_flag(TIF_NOTIFY_RESUME);                             \
  252.         false;                                                          \
  253. })
  254.  
  255. struct user_desc;
  256. extern int do_get_thread_area(struct task_struct *p, int idx,
  257.                               struct user_desc __user *info);
  258. extern int do_set_thread_area(struct task_struct *p, int idx,
  259.                               struct user_desc __user *info, int can_allocate);
  260.  
  261. #endif /* !__ASSEMBLY__ */
  262. #endif /* _ASM_X86_PTRACE_H */
  263.