From f48e48a6f3fe75a0329be4d63b1217f59292e4f9 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Tue, 2 Feb 2010 18:22:16 +0100 Subject: [PATCH] --- yaml --- r: 183019 b: refs/heads/master c: d23bc1b3a7e6db935acb9a949a5985d9b77dfd13 h: refs/heads/master i: 183017: e8ab5eedd3b56fc16bac3e586b07f7a86a5c7a83 183015: 7f34346e27394c5ed4065ac12f247042ead111fe v: v3 --- [refs] | 2 +- trunk/arch/arm/kernel/ptrace.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index c7876a074e90..9d9268a4ba45 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1a28e3d977860dc760909083df625b300f695680 +refs/heads/master: d23bc1b3a7e6db935acb9a949a5985d9b77dfd13 diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c index a2ea3854cb3c..bd56673c6a69 100644 --- a/trunk/arch/arm/kernel/ptrace.c +++ b/trunk/arch/arm/kernel/ptrace.c @@ -499,10 +499,41 @@ static struct undef_hook thumb_break_hook = { .fn = break_trap, }; +static int thumb2_break_trap(struct pt_regs *regs, unsigned int instr) +{ + unsigned int instr2; + void __user *pc; + + /* Check the second half of the instruction. */ + pc = (void __user *)(instruction_pointer(regs) + 2); + + if (processor_mode(regs) == SVC_MODE) { + instr2 = *(u16 *) pc; + } else { + get_user(instr2, (u16 __user *)pc); + } + + if (instr2 == 0xa000) { + ptrace_break(current, regs); + return 0; + } else { + return 1; + } +} + +static struct undef_hook thumb2_break_hook = { + .instr_mask = 0xffff, + .instr_val = 0xf7f0, + .cpsr_mask = PSR_T_BIT, + .cpsr_val = PSR_T_BIT, + .fn = thumb2_break_trap, +}; + static int __init ptrace_break_init(void) { register_undef_hook(&arm_break_hook); register_undef_hook(&thumb_break_hook); + register_undef_hook(&thumb2_break_hook); return 0; }