diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | runtime/uprobes/uprobes.c | 5 | ||||
-rw-r--r-- | runtime/uprobes/uprobes.h | 10 | ||||
-rw-r--r-- | runtime/uprobes/uprobes_i386.c | 20 | ||||
-rw-r--r-- | runtime/uprobes/uprobes_i386.h | 9 | ||||
-rw-r--r-- | runtime/uprobes/uprobes_ppc64.h | 9 | ||||
-rw-r--r-- | runtime/uprobes/uprobes_s390.h | 10 |
7 files changed, 52 insertions, 21 deletions
@@ -1,3 +1,13 @@ +2007-10-16 Jim Keniston <jkenisto@us.ibm.com> + + * runtime/uprobes/uprobes.[ch], uprobes_i386.[ch], + uprobes_ppc64.h, uprobes_s390.h: Adjusted SLOT_IP and + arch_validate_probed_insn to accept task pointer (needed by + x86_64); added uprobe_probept_arch_info and uprobe_task_arch_info + (ditto). + * runtime/uprobes/uprobes_i386.c: Fixed a couple of glitches + discovered when porting to x86_64 + 2007-10-15 Roland McGrath <roland@redhat.com> PR 5101 diff --git a/runtime/uprobes/uprobes.c b/runtime/uprobes/uprobes.c index 01b40670..9f5fddd0 100644 --- a/runtime/uprobes/uprobes.c +++ b/runtime/uprobes/uprobes.c @@ -251,7 +251,7 @@ static void insert_bkpt(struct uprobe_probept *ppt, struct task_struct *tsk) goto out; } - if ((result = arch_validate_probed_insn(ppt)) < 0) { + if ((result = arch_validate_probed_insn(ppt, tsk)) < 0) { bkpt_insertion_failed(ppt, "instruction type cannot be probed"); goto out; } @@ -1754,7 +1754,8 @@ static int utask_quiesce_pending_sigtrap(struct uprobe_task *utask) if (unlikely(regset == NULL)) return -EIO; - if ((*regset->get)(utask->tsk, regset, SLOT_IP * regset->size, + if ((*regset->get)(utask->tsk, regset, + SLOT_IP(utask->tsk) * regset->size, regset->size, &insn_ptr, NULL) != 0) return -EIO; diff --git a/runtime/uprobes/uprobes.h b/runtime/uprobes/uprobes.h index 84dd0b2a..e8a06599 100644 --- a/runtime/uprobes/uprobes.h +++ b/runtime/uprobes/uprobes.h @@ -278,9 +278,15 @@ struct uprobe_probept { /* Saved opcode (which has been replaced with breakpoint) */ uprobe_opcode_t opcode; - /* Saved original instruction */ + /* + * Saved original instruction. This may be modified by + * architecture-specific code if the original instruction + * can't be single-stepped out of line as-is. + */ uprobe_opcode_t insn[MAX_UINSN_BYTES / sizeof(uprobe_opcode_t)]; + struct uprobe_probept_arch_info arch_info; + /* The parent uprobe_process */ struct uprobe_process *uproc; @@ -359,6 +365,8 @@ struct uprobe_task { /* Saved address of copied original instruction */ long singlestep_addr; + struct uprobe_task_arch_info arch_info; + /* * Unexpected error in probepoint handling has left task's * text or stack corrupted. Kill task ASAP. diff --git a/runtime/uprobes/uprobes_i386.c b/runtime/uprobes/uprobes_i386.c index 21420681..5fe7d781 100644 --- a/runtime/uprobes/uprobes_i386.c +++ b/runtime/uprobes/uprobes_i386.c @@ -69,8 +69,8 @@ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* 90 */ W(0xa0, 1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,1)| /* a0 */ - W(0xb0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), /* b0 */ - W(0xc0, 1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1)| /* c0 */ + W(0xb0, 1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1), /* b0 */ + W(0xc0, 1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1)| /* c0 */ W(0xd0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* d0 */ W(0xe0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* e0 */ W(0xf0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) /* f0 */ @@ -80,10 +80,8 @@ /* * TODO: - * - Allow valid 2-byte opcodes (first byte = 0x0f). - * - Where necessary, examine the modrm byte and allow valid instructions + * - Where necessary, examine the modrm byte and allow only valid instructions * in the different Groups and fpu instructions. - * - Allow at least some instruction prefixes. * - Note: If we go past the first byte, do we need to verify that * subsequent bytes were actually there, rather than off the last page? * Probably overkill. We don't verify that they specified the first byte @@ -104,12 +102,11 @@ * fa, fb - cli, sti * * opcodes we may need to refine support for: - * 0f - valid 2-byte opcodes * 66 - data16 prefix * 8f - Group 1 - only reg = 0 is OK * c6-c7 - Group 11 - only reg = 0 is OK * d9-df - fpu insns with some illegal encodings - * fe - Group 4 - only reg = 1 or 2 is OK + * fe - Group 4 - only reg = 0 or 1 is OK * ff - Group 5 - only reg = 0-6 is OK * * others -- Do we need to support these? @@ -123,7 +120,8 @@ */ static -int arch_validate_probed_insn(struct uprobe_probept *ppt) +int arch_validate_probed_insn(struct uprobe_probept *ppt, + struct task_struct *tsk) { uprobe_opcode_t *insn = ppt->insn; @@ -138,9 +136,9 @@ int arch_validate_probed_insn(struct uprobe_probept *ppt) printk(KERN_ERR "uprobes does not currently support probing " "instructions with the 2-byte opcode 0x0f 0x%2.2x\n", insn[1]); - } - printk(KERN_ERR "uprobes does not currently support probing " - "instructions whose first byte is 0x%2.2x\n", insn[0]); + } else + printk(KERN_ERR "uprobes does not currently support probing " + "instructions whose first byte is 0x%2.2x\n", insn[0]); return -EPERM; } diff --git a/runtime/uprobes/uprobes_i386.h b/runtime/uprobes/uprobes_i386.h index 6e2aae70..e4376b95 100644 --- a/runtime/uprobes/uprobes_i386.h +++ b/runtime/uprobes/uprobes_i386.h @@ -32,17 +32,22 @@ typedef u8 uprobe_opcode_t; #define BREAKPOINT_INSTRUCTION 0xcc #define BP_INSN_SIZE 1 #define MAX_UINSN_BYTES 16 -#define SLOT_IP 12 /* instruction pointer slot from include/asm/elf.h */ +#define SLOT_IP(tsk) 12 /* instruction pointer slot from include/asm/elf.h */ #define BREAKPOINT_SIGNAL SIGTRAP #define SSTEP_SIGNAL SIGTRAP +struct uprobe_probept_arch_info {}; +struct uprobe_task_arch_info {}; + /* Architecture specific switch for where the IP points after a bp hit */ #define ARCH_BP_INST_PTR(inst_ptr) (inst_ptr - BP_INSN_SIZE) struct uprobe_probept; struct uprobe_task; -static int arch_validate_probed_insn(struct uprobe_probept *ppt); +struct task_struct; +static int arch_validate_probed_insn(struct uprobe_probept *ppt, + struct task_struct *tsk); /* On i386, the int3 traps leaves eip pointing past the int3 instruction. */ static inline unsigned long arch_get_probept(struct pt_regs *regs) diff --git a/runtime/uprobes/uprobes_ppc64.h b/runtime/uprobes/uprobes_ppc64.h index 619ba324..16e11975 100644 --- a/runtime/uprobes/uprobes_ppc64.h +++ b/runtime/uprobes/uprobes_ppc64.h @@ -34,15 +34,20 @@ typedef unsigned int uprobe_opcode_t; #define BREAKPOINT_INSTRUCTION 0x7fe00008 /* trap */ #define BP_INSN_SIZE 4 #define MAX_UINSN_BYTES 4 -#define SLOT_IP 32 /* instruction pointer slot from include/asm/elf.h */ +#define SLOT_IP(tsk) 32 /* instruction pointer slot from include/asm/elf.h */ + +struct uprobe_probept_arch_info {}; +struct uprobe_task_arch_info {}; /* Architecture specific switch for where the IP points after a bp hit */ #define ARCH_BP_INST_PTR(inst_ptr) (inst_ptr) struct uprobe_probept; struct uprobe_task; +struct task_struct; -static inline int arch_validate_probed_insn(struct uprobe_probept *ppt) +static inline int arch_validate_probed_insn(struct uprobe_probept *ppt, + struct task_struct *tsk); { return 0; } diff --git a/runtime/uprobes/uprobes_s390.h b/runtime/uprobes/uprobes_s390.h index 4f3a8187..5c711275 100644 --- a/runtime/uprobes/uprobes_s390.h +++ b/runtime/uprobes/uprobes_s390.h @@ -40,9 +40,9 @@ typedef u16 uprobe_opcode_t; #define SSTEP_SIGNAL SIGTRAP #ifdef CONFIG_COMPAT -#define SLOT_IP (test_tsk_thread_flag(current, TIF_31BIT) ? 0x04 : 0x08) +#define SLOT_IP(tsk) (test_tsk_thread_flag(tsk, TIF_31BIT) ? 0x04 : 0x08) #else -#define SLOT_IP 0x08 +#define SLOT_IP(tsk) 0x08 #endif #define FIXUP_PSW_NORMAL 0x08 @@ -50,12 +50,16 @@ typedef u16 uprobe_opcode_t; #define FIXUP_RETURN_REGISTER 0x02 #define FIXUP_NOT_REQUIRED 0x01 +struct uprobe_probept_arch_info {}; +struct uprobe_task_arch_info {}; + /* Architecture specific switch for where the IP points after a bp hit */ #define ARCH_BP_INST_PTR(inst_ptr) (inst_ptr - BP_INSN_SIZE) struct uprobe_probept; struct uprobe_task; -static int arch_validate_probed_insn(struct uprobe_probept *ppt); +static int arch_validate_probed_insn(struct uprobe_probept *ppt, + struct task_struct *tsk); /* * On s390, a trap leaves the instruction pointer pointing past the |