ptrace_64.c 16.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/* By Ross Biro 1/23/92 */
/*
 * Pentium III FXSR, SSE support
 *	Gareth Hughes <gareth@valinux.com>, May 2000
 * 
 * x86-64 port 2000-2002 Andi Kleen
 */

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/security.h>
#include <linux/audit.h>
#include <linux/seccomp.h>
19
#include <linux/signal.h>
L
Linus Torvalds 已提交
20 21 22 23 24

#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/processor.h>
R
Roland McGrath 已提交
25
#include <asm/prctl.h>
L
Linus Torvalds 已提交
26 27 28 29 30 31 32 33 34 35 36 37
#include <asm/i387.h>
#include <asm/debugreg.h>
#include <asm/ldt.h>
#include <asm/desc.h>
#include <asm/proto.h>
#include <asm/ia32.h>

/*
 * does not yet catch signals sent when the child dies.
 * in exit.c or in signal.c.
 */

38 39 40 41 42 43
/*
 * Determines which flags the user has access to [1 = access, 0 = no access].
 * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), IOPL(12-13), IF(9).
 * Also masks reserved bits (63-22, 15, 5, 3, 1).
 */
#define FLAG_MASK 0x54dd5UL
L
Linus Torvalds 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

/* set's the trap flag. */
#define TRAP_FLAG 0x100UL

/*
 * eflags and offset of eflags on child stack..
 */
#define EFLAGS offsetof(struct pt_regs, eflags)
#define EFL_OFFSET ((int)(EFLAGS-sizeof(struct pt_regs)))

/*
 * this routine will get a word off of the processes privileged stack. 
 * the offset is how far from the base addr as stored in the TSS.  
 * this routine assumes that all the privileged stacks are in our
 * data space.
 */   
static inline unsigned long get_stack_long(struct task_struct *task, int offset)
{
	unsigned char *stack;

	stack = (unsigned char *)task->thread.rsp0;
	stack += offset;
	return (*((unsigned long *)stack));
}

/*
 * this routine will put a word on the processes privileged stack. 
 * the offset is how far from the base addr as stored in the TSS.  
 * this routine assumes that all the privileged stacks are in our
 * data space.
 */
static inline long put_stack_long(struct task_struct *task, int offset,
	unsigned long data)
{
	unsigned char * stack;

	stack = (unsigned char *) task->thread.rsp0;
	stack += offset;
	*(unsigned long *) stack = data;
	return 0;
}

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
#define LDT_SEGMENT 4

unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *regs)
{
	unsigned long addr, seg;

	addr = regs->rip;
	seg = regs->cs & 0xffff;

	/*
	 * We'll assume that the code segments in the GDT
	 * are all zero-based. That is largely true: the
	 * TLS segments are used for data, and the PNPBIOS
	 * and APM bios ones we just ignore here.
	 */
	if (seg & LDT_SEGMENT) {
		u32 *desc;
		unsigned long base;

105
		seg &= ~7UL;
106

107
		mutex_lock(&child->mm->context.lock);
108 109 110 111 112 113 114 115 116 117 118 119 120
		if (unlikely((seg >> 3) >= child->mm->context.size))
			addr = -1L; /* bogus selector, access would fault */
		else {
			desc = child->mm->context.ldt + seg;
			base = ((desc[0] >> 16) |
				((desc[1] & 0xff) << 16) |
				(desc[1] & 0xff000000));

			/* 16-bit code segment? */
			if (!((desc[1] >> 22) & 1))
				addr &= 0xffff;
			addr += base;
		}
121
		mutex_unlock(&child->mm->context.lock);
122
	}
123

124 125 126
	return addr;
}

127
static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs)
128 129
{
	int i, copied;
130
	unsigned char opcode[15];
131 132 133 134 135
	unsigned long addr = convert_rip_to_linear(child, regs);

	copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
	for (i = 0; i < copied; i++) {
		switch (opcode[i]) {
136 137
		/* popf and iret */
		case 0x9d: case 0xcf:
138 139 140 141 142 143 144 145 146 147 148
			return 1;

			/* CHECKME: 64 65 */

		/* opcode and address size prefixes */
		case 0x66: case 0x67:
			continue;
		/* irrelevant prefixes (segment overrides and repeats) */
		case 0x26: case 0x2e:
		case 0x36: case 0x3e:
		case 0x64: case 0x65:
149
		case 0xf2: case 0xf3:
150 151 152
			continue;

		case 0x40 ... 0x4f:
153 154 155 156
			if (regs->cs != __USER_CS)
				/* 32-bit mode: register increment */
				return 0;
			/* 64-bit mode: REX prefix */
157 158
			continue;

159
			/* CHECKME: f2, f3 */
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175

		/*
		 * pushf: NOTE! We should probably not let
		 * the user see the TF bit being set. But
		 * it's more pain than it's worth to avoid
		 * it, and a debugger could emulate this
		 * all in user space if it _really_ cares.
		 */
		case 0x9c:
		default:
			return 0;
		}
	}
	return 0;
}

176 177
static void set_singlestep(struct task_struct *child)
{
A
Al Viro 已提交
178
	struct pt_regs *regs = task_pt_regs(child);
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195

	/*
	 * Always set TIF_SINGLESTEP - this guarantees that
	 * we single-step system calls etc..  This will also
	 * cause us to set TF when returning to user mode.
	 */
	set_tsk_thread_flag(child, TIF_SINGLESTEP);

	/*
	 * If TF was already set, don't do anything else
	 */
	if (regs->eflags & TRAP_FLAG)
		return;

	/* Set TF on the kernel stack.. */
	regs->eflags |= TRAP_FLAG;

196 197 198 199 200
	/*
	 * ..but if TF is changed by the instruction we will trace,
	 * don't mark it as being "us" that set it, so that we
	 * won't clear it by hand later.
	 */
201
	if (is_setting_trap_flag(child, regs))
202 203
		return;

204 205 206 207 208 209 210 211 212 213
	child->ptrace |= PT_DTRACE;
}

static void clear_singlestep(struct task_struct *child)
{
	/* Always clear TIF_SINGLESTEP... */
	clear_tsk_thread_flag(child, TIF_SINGLESTEP);

	/* But touch TF only if it was set by us.. */
	if (child->ptrace & PT_DTRACE) {
A
Al Viro 已提交
214
		struct pt_regs *regs = task_pt_regs(child);
215 216 217 218 219
		regs->eflags &= ~TRAP_FLAG;
		child->ptrace &= ~PT_DTRACE;
	}
}

L
Linus Torvalds 已提交
220 221 222 223 224 225 226
/*
 * Called by kernel/ptrace.c when detaching..
 *
 * Make sure the single step bit is not set.
 */
void ptrace_disable(struct task_struct *child)
{ 
227
	clear_singlestep(child);
L
Linus Torvalds 已提交
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
}

static int putreg(struct task_struct *child,
	unsigned long regno, unsigned long value)
{
	unsigned long tmp; 
	
	switch (regno) {
		case offsetof(struct user_regs_struct,fs):
			if (value && (value & 3) != 3)
				return -EIO;
			child->thread.fsindex = value & 0xffff; 
			return 0;
		case offsetof(struct user_regs_struct,gs):
			if (value && (value & 3) != 3)
				return -EIO;
			child->thread.gsindex = value & 0xffff;
			return 0;
		case offsetof(struct user_regs_struct,ds):
			if (value && (value & 3) != 3)
				return -EIO;
			child->thread.ds = value & 0xffff;
			return 0;
		case offsetof(struct user_regs_struct,es): 
			if (value && (value & 3) != 3)
				return -EIO;
			child->thread.es = value & 0xffff;
			return 0;
		case offsetof(struct user_regs_struct,ss):
			if ((value & 3) != 3)
				return -EIO;
			value &= 0xffff;
			return 0;
		case offsetof(struct user_regs_struct,fs_base):
262
			if (value >= TASK_SIZE_OF(child))
263
				return -EIO;
R
Roland McGrath 已提交
264 265 266 267 268 269 270
			/*
			 * When changing the segment base, use do_arch_prctl
			 * to set either thread.fs or thread.fsindex and the
			 * corresponding GDT slot.
			 */
			if (child->thread.fs != value)
				return do_arch_prctl(child, ARCH_SET_FS, value);
L
Linus Torvalds 已提交
271 272
			return 0;
		case offsetof(struct user_regs_struct,gs_base):
R
Roland McGrath 已提交
273 274 275
			/*
			 * Exactly the same here as the %fs handling above.
			 */
276
			if (value >= TASK_SIZE_OF(child))
277
				return -EIO;
R
Roland McGrath 已提交
278 279
			if (child->thread.gs != value)
				return do_arch_prctl(child, ARCH_SET_GS, value);
L
Linus Torvalds 已提交
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
			return 0;
		case offsetof(struct user_regs_struct, eflags):
			value &= FLAG_MASK;
			tmp = get_stack_long(child, EFL_OFFSET); 
			tmp &= ~FLAG_MASK; 
			value |= tmp;
			break;
		case offsetof(struct user_regs_struct,cs): 
			if ((value & 3) != 3)
				return -EIO;
			value &= 0xffff;
			break;
	}
	put_stack_long(child, regno - sizeof(struct pt_regs), value);
	return 0;
}

static unsigned long getreg(struct task_struct *child, unsigned long regno)
{
	unsigned long val;
	switch (regno) {
		case offsetof(struct user_regs_struct, fs):
			return child->thread.fsindex;
		case offsetof(struct user_regs_struct, gs):
			return child->thread.gsindex;
		case offsetof(struct user_regs_struct, ds):
			return child->thread.ds;
		case offsetof(struct user_regs_struct, es):
			return child->thread.es; 
		case offsetof(struct user_regs_struct, fs_base):
R
Roland McGrath 已提交
310 311 312 313 314 315 316 317 318 319
			/*
			 * do_arch_prctl may have used a GDT slot instead of
			 * the MSR.  To userland, it appears the same either
			 * way, except the %fs segment selector might not be 0.
			 */
			if (child->thread.fs != 0)
				return child->thread.fs;
			if (child->thread.fsindex != FS_TLS_SEL)
				return 0;
			return get_desc_base(&child->thread.tls_array[FS_TLS]);
L
Linus Torvalds 已提交
320
		case offsetof(struct user_regs_struct, gs_base):
R
Roland McGrath 已提交
321 322 323 324 325 326 327 328
			/*
			 * Exactly the same here as the %fs handling above.
			 */
			if (child->thread.gs != 0)
				return child->thread.gs;
			if (child->thread.gsindex != GS_TLS_SEL)
				return 0;
			return get_desc_base(&child->thread.tls_array[GS_TLS]);
L
Linus Torvalds 已提交
329 330 331 332 333 334 335 336 337 338
		default:
			regno = regno - sizeof(struct pt_regs);
			val = get_stack_long(child, regno);
			if (test_tsk_thread_flag(child, TIF_IA32))
				val &= 0xffffffff;
			return val;
	}

}

339
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
L
Linus Torvalds 已提交
340 341 342 343 344 345 346
{
	long i, ret;
	unsigned ui;

	switch (request) {
	/* when I and D space are separate, these will need to be fixed. */
	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
A
Alexey Dobriyan 已提交
347 348
	case PTRACE_PEEKDATA:
		ret = generic_ptrace_peekdata(child, addr, data);
L
Linus Torvalds 已提交
349 350 351 352 353 354 355 356 357 358 359 360
		break;

	/* read the word at location addr in the USER area. */
	case PTRACE_PEEKUSR: {
		unsigned long tmp;

		ret = -EIO;
		if ((addr & 7) ||
		    addr > sizeof(struct user) - 7)
			break;

		switch (addr) { 
361
		case 0 ... sizeof(struct user_regs_struct) - sizeof(long):
L
Linus Torvalds 已提交
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
			tmp = getreg(child, addr);
			break;
		case offsetof(struct user, u_debugreg[0]):
			tmp = child->thread.debugreg0;
			break;
		case offsetof(struct user, u_debugreg[1]):
			tmp = child->thread.debugreg1;
			break;
		case offsetof(struct user, u_debugreg[2]):
			tmp = child->thread.debugreg2;
			break;
		case offsetof(struct user, u_debugreg[3]):
			tmp = child->thread.debugreg3;
			break;
		case offsetof(struct user, u_debugreg[6]):
			tmp = child->thread.debugreg6;
			break;
		case offsetof(struct user, u_debugreg[7]):
			tmp = child->thread.debugreg7;
			break;
		default:
			tmp = 0;
			break;
		}
		ret = put_user(tmp,(unsigned long __user *) data);
		break;
	}

	/* when I and D space are separate, this will have to be fixed. */
	case PTRACE_POKETEXT: /* write the word at location addr. */
	case PTRACE_POKEDATA:
A
Alexey Dobriyan 已提交
393
		ret = generic_ptrace_pokedata(child, addr, data);
L
Linus Torvalds 已提交
394 395 396
		break;

	case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
397 398
	{
		int dsize = test_tsk_thread_flag(child, TIF_IA32) ? 3 : 7;
L
Linus Torvalds 已提交
399 400 401 402 403 404
		ret = -EIO;
		if ((addr & 7) ||
		    addr > sizeof(struct user) - 7)
			break;

		switch (addr) { 
405
		case 0 ... sizeof(struct user_regs_struct) - sizeof(long):
L
Linus Torvalds 已提交
406 407 408 409
			ret = putreg(child, addr, data);
			break;
		/* Disallows to set a breakpoint into the vsyscall */
		case offsetof(struct user, u_debugreg[0]):
410
			if (data >= TASK_SIZE_OF(child) - dsize) break;
L
Linus Torvalds 已提交
411 412 413 414
			child->thread.debugreg0 = data;
			ret = 0;
			break;
		case offsetof(struct user, u_debugreg[1]):
415
			if (data >= TASK_SIZE_OF(child) - dsize) break;
L
Linus Torvalds 已提交
416 417 418 419
			child->thread.debugreg1 = data;
			ret = 0;
			break;
		case offsetof(struct user, u_debugreg[2]):
420
			if (data >= TASK_SIZE_OF(child) - dsize) break;
L
Linus Torvalds 已提交
421 422 423 424
			child->thread.debugreg2 = data;
			ret = 0;
			break;
		case offsetof(struct user, u_debugreg[3]):
425
			if (data >= TASK_SIZE_OF(child) - dsize) break;
L
Linus Torvalds 已提交
426 427 428 429 430 431 432 433 434 435 436 437
			child->thread.debugreg3 = data;
			ret = 0;
			break;
		case offsetof(struct user, u_debugreg[6]):
				  if (data >> 32)
				break; 
			child->thread.debugreg6 = data;
			ret = 0;
			break;
		case offsetof(struct user, u_debugreg[7]):
			/* See arch/i386/kernel/ptrace.c for an explanation of
			 * this awkward check.*/
438 439 440
			data &= ~DR_CONTROL_RESERVED;
			for(i=0; i<4; i++)
				if ((0x5554 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
L
Linus Torvalds 已提交
441 442
					break;
			if (i == 4) {
443 444 445 446 447
			  child->thread.debugreg7 = data;
			  if (data)
			  	set_tsk_thread_flag(child, TIF_DEBUG);
			  else
			  	clear_tsk_thread_flag(child, TIF_DEBUG);
L
Linus Torvalds 已提交
448
			  ret = 0;
449
		  	}
L
Linus Torvalds 已提交
450 451 452
		  break;
		}
		break;
453
	}
L
Linus Torvalds 已提交
454
	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
455
	case PTRACE_CONT:    /* restart after signal. */
L
Linus Torvalds 已提交
456 457

		ret = -EIO;
458
		if (!valid_signal(data))
L
Linus Torvalds 已提交
459 460 461 462 463 464 465
			break;
		if (request == PTRACE_SYSCALL)
			set_tsk_thread_flag(child,TIF_SYSCALL_TRACE);
		else
			clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE);
		clear_tsk_thread_flag(child, TIF_SINGLESTEP);
		child->exit_code = data;
466 467
		/* make sure the single step bit is not set. */
		clear_singlestep(child);
L
Linus Torvalds 已提交
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
		wake_up_process(child);
		ret = 0;
		break;

#ifdef CONFIG_IA32_EMULATION
		/* This makes only sense with 32bit programs. Allow a
		   64bit debugger to fully examine them too. Better
		   don't use it against 64bit processes, use
		   PTRACE_ARCH_PRCTL instead. */
	case PTRACE_SET_THREAD_AREA: {
		struct user_desc __user *p;
		int old; 
		p = (struct user_desc __user *)data;
		get_user(old,  &p->entry_number); 
		put_user(addr, &p->entry_number);
		ret = do_set_thread_area(&child->thread, p);
		put_user(old,  &p->entry_number); 
		break;
	case PTRACE_GET_THREAD_AREA:
		p = (struct user_desc __user *)data;
		get_user(old,  &p->entry_number); 
		put_user(addr, &p->entry_number);
		ret = do_get_thread_area(&child->thread, p);
		put_user(old,  &p->entry_number); 
		break;
	} 
#endif
		/* normal 64bit interface to access TLS data. 
		   Works just like arch_prctl, except that the arguments
		   are reversed. */
	case PTRACE_ARCH_PRCTL: 
		ret = do_arch_prctl(child, data, addr);
		break;

/*
 * make the child exit.  Best I can do is send it a sigkill. 
 * perhaps it should be put in the status that it wants to 
 * exit.
 */
507
	case PTRACE_KILL:
L
Linus Torvalds 已提交
508 509 510 511 512 513
		ret = 0;
		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
			break;
		clear_tsk_thread_flag(child, TIF_SINGLESTEP);
		child->exit_code = SIGKILL;
		/* make sure the single step bit is not set. */
514
		clear_singlestep(child);
L
Linus Torvalds 已提交
515 516 517
		wake_up_process(child);
		break;

518
	case PTRACE_SINGLESTEP:    /* set the trap flag. */
L
Linus Torvalds 已提交
519
		ret = -EIO;
520
		if (!valid_signal(data))
L
Linus Torvalds 已提交
521 522
			break;
		clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE);
523
		set_singlestep(child);
L
Linus Torvalds 已提交
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
		child->exit_code = data;
		/* give it a chance to run. */
		wake_up_process(child);
		ret = 0;
		break;

	case PTRACE_GETREGS: { /* Get all gp regs from the child. */
	  	if (!access_ok(VERIFY_WRITE, (unsigned __user *)data,
			       sizeof(struct user_regs_struct))) {
			ret = -EIO;
			break;
		}
		ret = 0;
		for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) {
			ret |= __put_user(getreg(child, ui),(unsigned long __user *) data);
			data += sizeof(long);
		}
		break;
	}

	case PTRACE_SETREGS: { /* Set all gp regs in the child. */
		unsigned long tmp;
	  	if (!access_ok(VERIFY_READ, (unsigned __user *)data,
			       sizeof(struct user_regs_struct))) {
			ret = -EIO;
			break;
		}
		ret = 0;
		for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) {
553 554 555 556 557 558
			ret = __get_user(tmp, (unsigned long __user *) data);
			if (ret)
				break;
			ret = putreg(child, ui, tmp);
			if (ret)
				break;
L
Linus Torvalds 已提交
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
			data += sizeof(long);
		}
		break;
	}

	case PTRACE_GETFPREGS: { /* Get the child extended FPU state. */
		if (!access_ok(VERIFY_WRITE, (unsigned __user *)data,
			       sizeof(struct user_i387_struct))) {
			ret = -EIO;
			break;
		}
		ret = get_fpregs((struct user_i387_struct __user *)data, child);
		break;
	}

	case PTRACE_SETFPREGS: { /* Set the child extended FPU state. */
		if (!access_ok(VERIFY_READ, (unsigned __user *)data,
			       sizeof(struct user_i387_struct))) {
			ret = -EIO;
			break;
		}
		set_stopped_child_used_math(child);
		ret = set_fpregs(child, (struct user_i387_struct __user *)data);
		break;
	}

	default:
		ret = ptrace_request(child, request, addr, data);
		break;
	}
	return ret;
}

static void syscall_trace(struct pt_regs *regs)
{

#if 0
	printk("trace %s rip %lx rsp %lx rax %d origrax %d caller %lx tiflags %x ptrace %x\n",
	       current->comm,
	       regs->rip, regs->rsp, regs->rax, regs->orig_rax, __builtin_return_address(0),
	       current_thread_info()->flags, current->ptrace); 
#endif

	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
				? 0x80 : 0));
	/*
	 * this isn't the same as continuing with a signal, but it will do
	 * for normal use.  strace only continues with a signal if the
	 * stopping signal is not SIGTRAP.  -brl
	 */
	if (current->exit_code) {
		send_sig(current->exit_code, current, 1);
		current->exit_code = 0;
	}
}

asmlinkage void syscall_trace_enter(struct pt_regs *regs)
{
	/* do the secure computing check first */
	secure_computing(regs->orig_rax);

620 621 622 623
	if (test_thread_flag(TIF_SYSCALL_TRACE)
	    && (current->ptrace & PT_PTRACED))
		syscall_trace(regs);

624 625
	if (unlikely(current->audit_context)) {
		if (test_thread_flag(TIF_IA32)) {
626
			audit_syscall_entry(AUDIT_ARCH_I386,
627 628 629 630
					    regs->orig_rax,
					    regs->rbx, regs->rcx,
					    regs->rdx, regs->rsi);
		} else {
631
			audit_syscall_entry(AUDIT_ARCH_X86_64,
632 633 634 635 636
					    regs->orig_rax,
					    regs->rdi, regs->rsi,
					    regs->rdx, regs->r10);
		}
	}
L
Linus Torvalds 已提交
637 638 639 640 641
}

asmlinkage void syscall_trace_leave(struct pt_regs *regs)
{
	if (unlikely(current->audit_context))
642
		audit_syscall_exit(AUDITSC_RESULT(regs->rax), regs->rax);
L
Linus Torvalds 已提交
643 644 645 646 647 648

	if ((test_thread_flag(TIF_SYSCALL_TRACE)
	     || test_thread_flag(TIF_SINGLESTEP))
	    && (current->ptrace & PT_PTRACED))
		syscall_trace(regs);
}