Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ASM_X86_PTRACE_H
0003 #define _ASM_X86_PTRACE_H
0004 
0005 #include <asm/segment.h>
0006 #include <asm/page_types.h>
0007 #include <uapi/asm/ptrace.h>
0008 
0009 #ifndef __ASSEMBLY__
0010 #ifdef __i386__
0011 
0012 struct pt_regs {
0013     /*
0014      * NB: 32-bit x86 CPUs are inconsistent as what happens in the
0015      * following cases (where %seg represents a segment register):
0016      *
0017      * - pushl %seg: some do a 16-bit write and leave the high
0018      *   bits alone
0019      * - movl %seg, [mem]: some do a 16-bit write despite the movl
0020      * - IDT entry: some (e.g. 486) will leave the high bits of CS
0021      *   and (if applicable) SS undefined.
0022      *
0023      * Fortunately, x86-32 doesn't read the high bits on POP or IRET,
0024      * so we can just treat all of the segment registers as 16-bit
0025      * values.
0026      */
0027     unsigned long bx;
0028     unsigned long cx;
0029     unsigned long dx;
0030     unsigned long si;
0031     unsigned long di;
0032     unsigned long bp;
0033     unsigned long ax;
0034     unsigned short ds;
0035     unsigned short __dsh;
0036     unsigned short es;
0037     unsigned short __esh;
0038     unsigned short fs;
0039     unsigned short __fsh;
0040     /*
0041      * On interrupt, gs and __gsh store the vector number.  They never
0042      * store gs any more.
0043      */
0044     unsigned short gs;
0045     unsigned short __gsh;
0046     /* On interrupt, this is the error code. */
0047     unsigned long orig_ax;
0048     unsigned long ip;
0049     unsigned short cs;
0050     unsigned short __csh;
0051     unsigned long flags;
0052     unsigned long sp;
0053     unsigned short ss;
0054     unsigned short __ssh;
0055 };
0056 
0057 #else /* __i386__ */
0058 
0059 struct pt_regs {
0060 /*
0061  * C ABI says these regs are callee-preserved. They aren't saved on kernel entry
0062  * unless syscall needs a complete, fully filled "struct pt_regs".
0063  */
0064     unsigned long r15;
0065     unsigned long r14;
0066     unsigned long r13;
0067     unsigned long r12;
0068     unsigned long bp;
0069     unsigned long bx;
0070 /* These regs are callee-clobbered. Always saved on kernel entry. */
0071     unsigned long r11;
0072     unsigned long r10;
0073     unsigned long r9;
0074     unsigned long r8;
0075     unsigned long ax;
0076     unsigned long cx;
0077     unsigned long dx;
0078     unsigned long si;
0079     unsigned long di;
0080 /*
0081  * On syscall entry, this is syscall#. On CPU exception, this is error code.
0082  * On hw interrupt, it's IRQ number:
0083  */
0084     unsigned long orig_ax;
0085 /* Return frame for iretq */
0086     unsigned long ip;
0087     unsigned long cs;
0088     unsigned long flags;
0089     unsigned long sp;
0090     unsigned long ss;
0091 /* top of stack page */
0092 };
0093 
0094 #endif /* !__i386__ */
0095 
0096 #ifdef CONFIG_PARAVIRT
0097 #include <asm/paravirt_types.h>
0098 #endif
0099 
0100 #include <asm/proto.h>
0101 
0102 struct cpuinfo_x86;
0103 struct task_struct;
0104 
0105 extern unsigned long profile_pc(struct pt_regs *regs);
0106 
0107 extern unsigned long
0108 convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
0109 extern void send_sigtrap(struct pt_regs *regs, int error_code, int si_code);
0110 
0111 
0112 static inline unsigned long regs_return_value(struct pt_regs *regs)
0113 {
0114     return regs->ax;
0115 }
0116 
0117 static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
0118 {
0119     regs->ax = rc;
0120 }
0121 
0122 /*
0123  * user_mode(regs) determines whether a register set came from user
0124  * mode.  On x86_32, this is true if V8086 mode was enabled OR if the
0125  * register set was from protected mode with RPL-3 CS value.  This
0126  * tricky test checks that with one comparison.
0127  *
0128  * On x86_64, vm86 mode is mercifully nonexistent, and we don't need
0129  * the extra check.
0130  */
0131 static __always_inline int user_mode(struct pt_regs *regs)
0132 {
0133 #ifdef CONFIG_X86_32
0134     return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL;
0135 #else
0136     return !!(regs->cs & 3);
0137 #endif
0138 }
0139 
0140 static __always_inline int v8086_mode(struct pt_regs *regs)
0141 {
0142 #ifdef CONFIG_X86_32
0143     return (regs->flags & X86_VM_MASK);
0144 #else
0145     return 0;   /* No V86 mode support in long mode */
0146 #endif
0147 }
0148 
0149 static inline bool user_64bit_mode(struct pt_regs *regs)
0150 {
0151 #ifdef CONFIG_X86_64
0152 #ifndef CONFIG_PARAVIRT_XXL
0153     /*
0154      * On non-paravirt systems, this is the only long mode CPL 3
0155      * selector.  We do not allow long mode selectors in the LDT.
0156      */
0157     return regs->cs == __USER_CS;
0158 #else
0159     /* Headers are too twisted for this to go in paravirt.h. */
0160     return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs;
0161 #endif
0162 #else /* !CONFIG_X86_64 */
0163     return false;
0164 #endif
0165 }
0166 
0167 /*
0168  * Determine whether the register set came from any context that is running in
0169  * 64-bit mode.
0170  */
0171 static inline bool any_64bit_mode(struct pt_regs *regs)
0172 {
0173 #ifdef CONFIG_X86_64
0174     return !user_mode(regs) || user_64bit_mode(regs);
0175 #else
0176     return false;
0177 #endif
0178 }
0179 
0180 #ifdef CONFIG_X86_64
0181 #define current_user_stack_pointer()    current_pt_regs()->sp
0182 #define compat_user_stack_pointer() current_pt_regs()->sp
0183 
0184 static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs)
0185 {
0186     bool ret = (regs->ip >= (unsigned long)entry_SYSCALL_64 &&
0187             regs->ip <  (unsigned long)entry_SYSCALL_64_safe_stack);
0188 
0189     ret = ret || (regs->ip >= (unsigned long)entry_SYSRETQ_unsafe_stack &&
0190               regs->ip <  (unsigned long)entry_SYSRETQ_end);
0191 #ifdef CONFIG_IA32_EMULATION
0192     ret = ret || (regs->ip >= (unsigned long)entry_SYSCALL_compat &&
0193               regs->ip <  (unsigned long)entry_SYSCALL_compat_safe_stack);
0194     ret = ret || (regs->ip >= (unsigned long)entry_SYSRETL_compat_unsafe_stack &&
0195               regs->ip <  (unsigned long)entry_SYSRETL_compat_end);
0196 #endif
0197 
0198     return ret;
0199 }
0200 #endif
0201 
0202 static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
0203 {
0204     return regs->sp;
0205 }
0206 
0207 static inline unsigned long instruction_pointer(struct pt_regs *regs)
0208 {
0209     return regs->ip;
0210 }
0211 
0212 static inline void instruction_pointer_set(struct pt_regs *regs,
0213         unsigned long val)
0214 {
0215     regs->ip = val;
0216 }
0217 
0218 static inline unsigned long frame_pointer(struct pt_regs *regs)
0219 {
0220     return regs->bp;
0221 }
0222 
0223 static inline unsigned long user_stack_pointer(struct pt_regs *regs)
0224 {
0225     return regs->sp;
0226 }
0227 
0228 static inline void user_stack_pointer_set(struct pt_regs *regs,
0229         unsigned long val)
0230 {
0231     regs->sp = val;
0232 }
0233 
0234 static __always_inline bool regs_irqs_disabled(struct pt_regs *regs)
0235 {
0236     return !(regs->flags & X86_EFLAGS_IF);
0237 }
0238 
0239 /* Query offset/name of register from its name/offset */
0240 extern int regs_query_register_offset(const char *name);
0241 extern const char *regs_query_register_name(unsigned int offset);
0242 #define MAX_REG_OFFSET (offsetof(struct pt_regs, ss))
0243 
0244 /**
0245  * regs_get_register() - get register value from its offset
0246  * @regs:   pt_regs from which register value is gotten.
0247  * @offset: offset number of the register.
0248  *
0249  * regs_get_register returns the value of a register. The @offset is the
0250  * offset of the register in struct pt_regs address which specified by @regs.
0251  * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
0252  */
0253 static inline unsigned long regs_get_register(struct pt_regs *regs,
0254                           unsigned int offset)
0255 {
0256     if (unlikely(offset > MAX_REG_OFFSET))
0257         return 0;
0258 #ifdef CONFIG_X86_32
0259     /* The selector fields are 16-bit. */
0260     if (offset == offsetof(struct pt_regs, cs) ||
0261         offset == offsetof(struct pt_regs, ss) ||
0262         offset == offsetof(struct pt_regs, ds) ||
0263         offset == offsetof(struct pt_regs, es) ||
0264         offset == offsetof(struct pt_regs, fs) ||
0265         offset == offsetof(struct pt_regs, gs)) {
0266         return *(u16 *)((unsigned long)regs + offset);
0267 
0268     }
0269 #endif
0270     return *(unsigned long *)((unsigned long)regs + offset);
0271 }
0272 
0273 /**
0274  * regs_within_kernel_stack() - check the address in the stack
0275  * @regs:   pt_regs which contains kernel stack pointer.
0276  * @addr:   address which is checked.
0277  *
0278  * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
0279  * If @addr is within the kernel stack, it returns true. If not, returns false.
0280  */
0281 static inline int regs_within_kernel_stack(struct pt_regs *regs,
0282                        unsigned long addr)
0283 {
0284     return ((addr & ~(THREAD_SIZE - 1)) == (regs->sp & ~(THREAD_SIZE - 1)));
0285 }
0286 
0287 /**
0288  * regs_get_kernel_stack_nth_addr() - get the address of the Nth entry on stack
0289  * @regs:   pt_regs which contains kernel stack pointer.
0290  * @n:      stack entry number.
0291  *
0292  * regs_get_kernel_stack_nth() returns the address of the @n th entry of the
0293  * kernel stack which is specified by @regs. If the @n th entry is NOT in
0294  * the kernel stack, this returns NULL.
0295  */
0296 static inline unsigned long *regs_get_kernel_stack_nth_addr(struct pt_regs *regs, unsigned int n)
0297 {
0298     unsigned long *addr = (unsigned long *)regs->sp;
0299 
0300     addr += n;
0301     if (regs_within_kernel_stack(regs, (unsigned long)addr))
0302         return addr;
0303     else
0304         return NULL;
0305 }
0306 
0307 /* To avoid include hell, we can't include uaccess.h */
0308 extern long copy_from_kernel_nofault(void *dst, const void *src, size_t size);
0309 
0310 /**
0311  * regs_get_kernel_stack_nth() - get Nth entry of the stack
0312  * @regs:   pt_regs which contains kernel stack pointer.
0313  * @n:      stack entry number.
0314  *
0315  * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
0316  * is specified by @regs. If the @n th entry is NOT in the kernel stack
0317  * this returns 0.
0318  */
0319 static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
0320                               unsigned int n)
0321 {
0322     unsigned long *addr;
0323     unsigned long val;
0324     long ret;
0325 
0326     addr = regs_get_kernel_stack_nth_addr(regs, n);
0327     if (addr) {
0328         ret = copy_from_kernel_nofault(&val, addr, sizeof(val));
0329         if (!ret)
0330             return val;
0331     }
0332     return 0;
0333 }
0334 
0335 /**
0336  * regs_get_kernel_argument() - get Nth function argument in kernel
0337  * @regs:   pt_regs of that context
0338  * @n:      function argument number (start from 0)
0339  *
0340  * regs_get_argument() returns @n th argument of the function call.
0341  * Note that this chooses most probably assignment, in some case
0342  * it can be incorrect.
0343  * This is expected to be called from kprobes or ftrace with regs
0344  * where the top of stack is the return address.
0345  */
0346 static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,
0347                              unsigned int n)
0348 {
0349     static const unsigned int argument_offs[] = {
0350 #ifdef __i386__
0351         offsetof(struct pt_regs, ax),
0352         offsetof(struct pt_regs, dx),
0353         offsetof(struct pt_regs, cx),
0354 #define NR_REG_ARGUMENTS 3
0355 #else
0356         offsetof(struct pt_regs, di),
0357         offsetof(struct pt_regs, si),
0358         offsetof(struct pt_regs, dx),
0359         offsetof(struct pt_regs, cx),
0360         offsetof(struct pt_regs, r8),
0361         offsetof(struct pt_regs, r9),
0362 #define NR_REG_ARGUMENTS 6
0363 #endif
0364     };
0365 
0366     if (n >= NR_REG_ARGUMENTS) {
0367         n -= NR_REG_ARGUMENTS - 1;
0368         return regs_get_kernel_stack_nth(regs, n);
0369     } else
0370         return regs_get_register(regs, argument_offs[n]);
0371 }
0372 
0373 #define arch_has_single_step()  (1)
0374 #ifdef CONFIG_X86_DEBUGCTLMSR
0375 #define arch_has_block_step()   (1)
0376 #else
0377 #define arch_has_block_step()   (boot_cpu_data.x86 >= 6)
0378 #endif
0379 
0380 #define ARCH_HAS_USER_SINGLE_STEP_REPORT
0381 
0382 struct user_desc;
0383 extern int do_get_thread_area(struct task_struct *p, int idx,
0384                   struct user_desc __user *info);
0385 extern int do_set_thread_area(struct task_struct *p, int idx,
0386                   struct user_desc __user *info, int can_allocate);
0387 
0388 #ifdef CONFIG_X86_64
0389 # define do_set_thread_area_64(p, s, t) do_arch_prctl_64(p, s, t)
0390 #else
0391 # define do_set_thread_area_64(p, s, t) (0)
0392 #endif
0393 
0394 #endif /* !__ASSEMBLY__ */
0395 #endif /* _ASM_X86_PTRACE_H */