0001
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
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
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
0042
0043
0044 unsigned short gs;
0045 unsigned short __gsh;
0046
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
0058
0059 struct pt_regs {
0060
0061
0062
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
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
0082
0083
0084 unsigned long orig_ax;
0085
0086 unsigned long ip;
0087 unsigned long cs;
0088 unsigned long flags;
0089 unsigned long sp;
0090 unsigned long ss;
0091
0092 };
0093
0094 #endif
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
0124
0125
0126
0127
0128
0129
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;
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
0155
0156
0157 return regs->cs == __USER_CS;
0158 #else
0159
0160 return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs;
0161 #endif
0162 #else
0163 return false;
0164 #endif
0165 }
0166
0167
0168
0169
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
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
0246
0247
0248
0249
0250
0251
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
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
0275
0276
0277
0278
0279
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
0289
0290
0291
0292
0293
0294
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
0308 extern long copy_from_kernel_nofault(void *dst, const void *src, size_t size);
0309
0310
0311
0312
0313
0314
0315
0316
0317
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
0337
0338
0339
0340
0341
0342
0343
0344
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
0395 #endif