* [PATCH 1/3] Kprobes: Make kprobe modules more portable
@ 2006-08-07 11:55 Ananth N Mavinakayanahalli
2006-08-07 12:00 ` [PATCH 2/3] Kprobes: Define retval helper Ananth N Mavinakayanahalli
` (2 more replies)
0 siblings, 3 replies; 29+ messages in thread
From: Ananth N Mavinakayanahalli @ 2006-08-07 11:55 UTC (permalink / raw)
To: linux-kernel
From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
This patch introduces KPROBE_ADDR, a macro that abstracts out the
architecture-specific artefacts of getting the correct text address
given a symbol. While we are at it, also introduce the symbol_name field
in struct kprobe to allow for users to just specify the address to be
probed in terms of the kernel symbol. In-kernel kprobes infrastructure
decodes the actual text address to probe. The symbol resolution happens
only if the kprobe.addr isn't explicitly specified.
---
Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Signed-off-by: Prasanna S.P <prasanna@in.ibm.com>
---
include/asm-powerpc/kprobes.h | 2 ++
include/linux/kprobes.h | 8 ++++++++
kernel/kprobes.c | 4 ++++
3 files changed, 14 insertions(+)
Index: linux-2.6.18-rc3/include/asm-powerpc/kprobes.h
===================================================================
--- linux-2.6.18-rc3.orig/include/asm-powerpc/kprobes.h
+++ linux-2.6.18-rc3/include/asm-powerpc/kprobes.h
@@ -44,6 +44,8 @@ typedef unsigned int kprobe_opcode_t;
#define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000)
#define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000)
+#define KPROBE_ADDR(name) *((kprobe_opcode_t **)(kallsyms_lookup_name(name)))
+
#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry)
#define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \
Index: linux-2.6.18-rc3/include/linux/kprobes.h
===================================================================
--- linux-2.6.18-rc3.orig/include/linux/kprobes.h
+++ linux-2.6.18-rc3/include/linux/kprobes.h
@@ -36,6 +36,7 @@
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
#include <linux/mutex.h>
+#include <linux/kallsyms.h>
#ifdef CONFIG_KPROBES
#include <asm/kprobes.h>
@@ -49,6 +50,10 @@
/* Attach to insert probes on any functions which should be ignored*/
#define __kprobes __attribute__((__section__(".kprobes.text")))
+#ifndef KPROBE_ADDR /* powerpc has its own definition */
+#define KPROBE_ADDR(name) (kprobe_opcode_t *)(kallsyms_lookup_name(name))
+#endif /* KPROBE_ADDR */
+
struct kprobe;
struct pt_regs;
struct kretprobe;
@@ -77,6 +82,9 @@ struct kprobe {
/* location of the probe point */
kprobe_opcode_t *addr;
+ /* Allow user to indicate symbol name of the probe point */
+ char *symbol_name;
+
/* Called before addr is executed. */
kprobe_pre_handler_t pre_handler;
Index: linux-2.6.18-rc3/kernel/kprobes.c
===================================================================
--- linux-2.6.18-rc3.orig/kernel/kprobes.c
+++ linux-2.6.18-rc3/kernel/kprobes.c
@@ -446,6 +446,10 @@ static int __kprobes __register_kprobe(s
struct kprobe *old_p;
struct module *probed_mod;
+ /* Do the kallsyms lookup only if p->addr == NULL */
+ if (!p->addr && (p->symbol_name))
+ p->addr = KPROBE_ADDR(p->symbol_name);
+
if ((!kernel_text_address((unsigned long) p->addr)) ||
in_kprobes_functions((unsigned long) p->addr))
return -EINVAL;
^ permalink raw reply [flat|nested] 29+ messages in thread* [PATCH 2/3] Kprobes: Define retval helper 2006-08-07 11:55 [PATCH 1/3] Kprobes: Make kprobe modules more portable Ananth N Mavinakayanahalli @ 2006-08-07 12:00 ` Ananth N Mavinakayanahalli 2006-08-07 12:04 ` [PATCH 3/3] Kprobes: Update Documentation/kprobes.txt Ananth N Mavinakayanahalli 2006-08-08 16:25 ` [PATCH 2/3] Kprobes: Define retval helper Christoph Hellwig 2006-08-07 12:06 ` [PATCH 1/3] Kprobes: Make kprobe modules more portable Ananth N Mavinakayanahalli 2006-08-08 16:24 ` Christoph Hellwig 2 siblings, 2 replies; 29+ messages in thread From: Ananth N Mavinakayanahalli @ 2006-08-07 12:00 UTC (permalink / raw) To: linux-kernel; +Cc: Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Add the KPROBE_RETVAL macro to help extract the return value on different architectures, while using function-return probes. --- Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> Signed-off-by: Prasanna S.P <prasanna@in.ibm.com> --- include/asm-i386/kprobes.h | 2 ++ include/asm-ia64/kprobes.h | 2 ++ include/asm-powerpc/kprobes.h | 2 ++ include/asm-x86_64/kprobes.h | 2 ++ 4 files changed, 8 insertions(+) Index: linux-2.6.18-rc3/include/asm-i386/kprobes.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-i386/kprobes.h +++ linux-2.6.18-rc3/include/asm-i386/kprobes.h @@ -46,6 +46,8 @@ typedef u8 kprobe_opcode_t; #define ARCH_SUPPORTS_KRETPROBES #define ARCH_INACTIVE_KPROBE_COUNT 0 +#define KPROBE_RETVAL(regs) regs->eax + void arch_remove_kprobe(struct kprobe *p); void kretprobe_trampoline(void); Index: linux-2.6.18-rc3/include/asm-ia64/kprobes.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-ia64/kprobes.h +++ linux-2.6.18-rc3/include/asm-ia64/kprobes.h @@ -84,6 +84,8 @@ struct kprobe_ctlblk { #define ARCH_SUPPORTS_KRETPROBES #define ARCH_INACTIVE_KPROBE_COUNT 1 +#define KPROBE_RETVAL(regs) regs->r8 + #define SLOT0_OPCODE_SHIFT (37) #define SLOT1_p1_OPCODE_SHIFT (37 - (64-46)) #define SLOT2_OPCODE_SHIFT (37) Index: linux-2.6.18-rc3/include/asm-powerpc/kprobes.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-powerpc/kprobes.h +++ linux-2.6.18-rc3/include/asm-powerpc/kprobes.h @@ -54,6 +54,8 @@ typedef unsigned int kprobe_opcode_t; #define ARCH_SUPPORTS_KRETPROBES #define ARCH_INACTIVE_KPROBE_COUNT 1 +#define KPROBE_RETVAL(regs) regs->gpr[3] + void kretprobe_trampoline(void); extern void arch_remove_kprobe(struct kprobe *p); Index: linux-2.6.18-rc3/include/asm-x86_64/kprobes.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-x86_64/kprobes.h +++ linux-2.6.18-rc3/include/asm-x86_64/kprobes.h @@ -45,6 +45,8 @@ typedef u8 kprobe_opcode_t; #define ARCH_SUPPORTS_KRETPROBES #define ARCH_INACTIVE_KPROBE_COUNT 1 +#define KPROBE_RETVAL(regs) regs->rax + void kretprobe_trampoline(void); extern void arch_remove_kprobe(struct kprobe *p); ^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 3/3] Kprobes: Update Documentation/kprobes.txt 2006-08-07 12:00 ` [PATCH 2/3] Kprobes: Define retval helper Ananth N Mavinakayanahalli @ 2006-08-07 12:04 ` Ananth N Mavinakayanahalli 2006-08-08 16:27 ` Christoph Hellwig 2006-08-08 16:25 ` [PATCH 2/3] Kprobes: Define retval helper Christoph Hellwig 1 sibling, 1 reply; 29+ messages in thread From: Ananth N Mavinakayanahalli @ 2006-08-07 12:04 UTC (permalink / raw) To: linux-kernel; +Cc: Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Update Documentation/kprobes.txt to reflect addition of KPROBE_ADDR, KPROBE_RETVAL and the in-kernel symbol resolution. While at it: - Document usage of JPROBE_RETURN - Update the references list - Update module examples to use module_init/module_exit interfaces --- Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Acked-by: Jim Keniston <jkenisto@us.ibm.com> --- Documentation/kprobes.txt | 77 ++++++++++++++++++++++++++++------------------ 1 files changed, 47 insertions(+), 30 deletions(-) Index: linux-2.6.18-rc3/Documentation/kprobes.txt =================================================================== --- linux-2.6.18-rc3.orig/Documentation/kprobes.txt +++ linux-2.6.18-rc3/Documentation/kprobes.txt @@ -179,6 +179,21 @@ occurs during execution of kp->pre_handl or during single-stepping of the probed instruction, Kprobes calls kp->fault_handler. Any or all handlers can be NULL. +NOTE: +1. The KPROBE_ADDR macro is provided as an aid to make kprobe modules +portable. Some architectures (notably powerpc) uses function descriptors +due to which a kallsyms_lookup_name("probepoint") will give a data address, +which, incidentally, is a placeholder for the actual text address. It is +therefore advised to use: + + kp.addr = KPROBE_ADDR("probepoint"); + +2. With the introduction of the "symbol_name" field to struct kprobe, +the probepoint address resolution will now be taken care of by the kernel. +The following will also work: + + kp.symbol_name = "symbol_name"; + register_kprobe() returns 0 on success, or a negative errno otherwise. User's pre-handler (kp->pre_handler): @@ -225,6 +240,12 @@ control to Kprobes.) If the probed func fastcall, or anything else that affects how args are passed, the handler's declaration must match. +NOTE: Similar to KPROBE_ADDR, a macro JPROBE_ENTRY is provided to handle +architecture-specific aliasing of jp->entry. In the interest of +portability, it is advised to use: + + jp->entry = JPROBE_ENTRY(handler); + register_jprobe() returns 0 on success, or a negative errno otherwise. 4.3 register_kretprobe @@ -251,6 +272,11 @@ of interest: - ret_addr: the return address - rp: points to the corresponding kretprobe object - task: points to the corresponding task struct + +The KPROBE_RETVAL(regs) macro provides a simple abstraction to extract +the return value from the appropriate register as defined by the +architecture's ABI. + The handler's return value is currently ignored. 4.4 unregister_*probe @@ -369,7 +395,6 @@ stack trace and selected i386 registers #include <linux/kernel.h> #include <linux/module.h> #include <linux/kprobes.h> -#include <linux/kallsyms.h> #include <linux/sched.h> /*For each probe you need to allocate a kprobe structure*/ @@ -403,18 +428,14 @@ int handler_fault(struct kprobe *p, stru return 0; } -int init_module(void) +static int __init kprobe_init(void) { int ret; kp.pre_handler = handler_pre; kp.post_handler = handler_post; kp.fault_handler = handler_fault; - kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork"); - /* register the kprobe now */ - if (!kp.addr) { - printk("Couldn't find %s to plant kprobe\n", "do_fork"); - return -1; - } + kp.symbol_name = "do_fork"; + if ((ret = register_kprobe(&kp) < 0)) { printk("register_kprobe failed, returned %d\n", ret); return -1; @@ -423,12 +444,14 @@ int init_module(void) return 0; } -void cleanup_module(void) +static void __exit kprobe_exit(void) { unregister_kprobe(&kp); printk("kprobe unregistered\n"); } +module_init(kprobe_init) +module_exit(kprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -463,7 +486,6 @@ the arguments of do_fork(). #include <linux/fs.h> #include <linux/uio.h> #include <linux/kprobes.h> -#include <linux/kallsyms.h> /* * Jumper probe for do_fork. @@ -485,17 +507,13 @@ long jdo_fork(unsigned long clone_flags, } static struct jprobe my_jprobe = { - .entry = (kprobe_opcode_t *) jdo_fork + .entry = JPROBE_ENTRY(jdo_fork) }; -int init_module(void) +static int __init jprobe_init(void) { int ret; - my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork"); - if (!my_jprobe.kp.addr) { - printk("Couldn't find %s to plant jprobe\n", "do_fork"); - return -1; - } + my_jprobe.kp.symbol_name = "do_fork"; if ((ret = register_jprobe(&my_jprobe)) <0) { printk("register_jprobe failed, returned %d\n", ret); @@ -506,12 +524,14 @@ int init_module(void) return 0; } -void cleanup_module(void) +static void __exit jprobe_exit(void) { unregister_jprobe(&my_jprobe); printk("jprobe unregistered\n"); } +module_init(jprobe_init) +module_exit(jprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -530,16 +550,13 @@ report failed calls to sys_open(). #include <linux/kernel.h> #include <linux/module.h> #include <linux/kprobes.h> -#include <linux/kallsyms.h> static const char *probed_func = "sys_open"; /* Return-probe handler: If the probed function fails, log the return value. */ static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { - // Substitute the appropriate register name for your architecture -- - // e.g., regs->rax for x86_64, regs->gpr[3] for ppc64. - int retval = (int) regs->eax; + int retval = KPROBE_RETVAL(regs); if (retval < 0) { printk("%s returns %d\n", probed_func, retval); } @@ -552,15 +569,11 @@ static struct kretprobe my_kretprobe = { .maxactive = 20 }; -int init_module(void) +static int __init kretprobe_init(void) { int ret; - my_kretprobe.kp.addr = - (kprobe_opcode_t *) kallsyms_lookup_name(probed_func); - if (!my_kretprobe.kp.addr) { - printk("Couldn't find %s to plant return probe\n", probed_func); - return -1; - } + my_kretprobe.kp.symbol_name = (char *)probed_func; + if ((ret = register_kretprobe(&my_kretprobe)) < 0) { printk("register_kretprobe failed, returned %d\n", ret); return -1; @@ -569,7 +582,7 @@ int init_module(void) return 0; } -void cleanup_module(void) +static void __exit kretprobe_exit(void) { unregister_kretprobe(&my_kretprobe); printk("kretprobe unregistered\n"); @@ -578,6 +591,8 @@ void cleanup_module(void) my_kretprobe.nmissed, probed_func); } +module_init(kretprobe_init) +module_exit(kretprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -590,3 +605,5 @@ messages.) For additional information on Kprobes, refer to the following URLs: http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe http://www.redhat.com/magazine/005mar05/features/kprobes/ +http://www-users.cs.umn.edu/~boutcher/kprobes/ +http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 3/3] Kprobes: Update Documentation/kprobes.txt 2006-08-07 12:04 ` [PATCH 3/3] Kprobes: Update Documentation/kprobes.txt Ananth N Mavinakayanahalli @ 2006-08-08 16:27 ` Christoph Hellwig 2006-08-09 9:48 ` Ananth N Mavinakayanahalli 0 siblings, 1 reply; 29+ messages in thread From: Christoph Hellwig @ 2006-08-08 16:27 UTC (permalink / raw) To: Ananth N Mavinakayanahalli Cc: linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston On Mon, Aug 07, 2006 at 05:34:47PM +0530, Ananth N Mavinakayanahalli wrote: > From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > > Update Documentation/kprobes.txt to reflect addition of KPROBE_ADDR, > KPROBE_RETVAL and the in-kernel symbol resolution. Thanks. With my updated patch we shouldn't document KPROBE_ADDR anymore but tell people to always use the symbol_name mechanisms. Any chance to add some kerneldoc comments for the exported kprobes functions? ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 3/3] Kprobes: Update Documentation/kprobes.txt 2006-08-08 16:27 ` Christoph Hellwig @ 2006-08-09 9:48 ` Ananth N Mavinakayanahalli 2006-08-09 10:24 ` Ananth N Mavinakayanahalli 0 siblings, 1 reply; 29+ messages in thread From: Ananth N Mavinakayanahalli @ 2006-08-09 9:48 UTC (permalink / raw) To: Christoph Hellwig, linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston On Tue, Aug 08, 2006 at 05:27:01PM +0100, Christoph Hellwig wrote: > On Mon, Aug 07, 2006 at 05:34:47PM +0530, Ananth N Mavinakayanahalli wrote: > > From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > > > > Update Documentation/kprobes.txt to reflect addition of KPROBE_ADDR, > > KPROBE_RETVAL and the in-kernel symbol resolution. > > Thanks. With my updated patch we shouldn't document KPROBE_ADDR anymore > but tell people to always use the symbol_name mechanisms. Done! Updated patch to documentation below. > Any chance to add some kerneldoc comments for the exported kprobes > functions? Its on the TODO list along with the other CodingStyle cleanups. Ananth --- Update Documentation/kprobes.txt: - Add usage details of "symbol_name" and "offset" fields of struct kprobe - Document JPROBE_ENTRY - Update references list - Update module examples to use module_init/module_exit interfaces Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> --- Documentation/kprobes.txt | 77 ++++++++++++++++++++++++++++------------------ 1 files changed, 47 insertions(+), 30 deletions(-) Index: linux-2.6.18-rc3/Documentation/kprobes.txt =================================================================== --- linux-2.6.18-rc3.orig/Documentation/kprobes.txt +++ linux-2.6.18-rc3/Documentation/kprobes.txt @@ -179,6 +179,21 @@ occurs during execution of kp->pre_handl or during single-stepping of the probed instruction, Kprobes calls kp->fault_handler. Any or all handlers can be NULL. +NOTE: +1. With the introduction of the "symbol_name" field to struct kprobe, +the probepoint address resolution will now be taken care of by the kernel. +The following will now work: + + kp.symbol_name = "symbol_name"; + +2. Use the "offset" field of struct kprobe if the offset into the symbol +to install a probepoint is known. This field is used to calculate the +probepoint address only if the "symbol_name" method of address resolution +is used. + +3. Specify either the kprobe "symbol_name" with "offset" OR the "addr". +If both are specified, kprobe registration will fail with -EINVAL. + register_kprobe() returns 0 on success, or a negative errno otherwise. User's pre-handler (kp->pre_handler): @@ -225,6 +240,12 @@ control to Kprobes.) If the probed func fastcall, or anything else that affects how args are passed, the handler's declaration must match. +NOTE: A macro JPROBE_ENTRY is provided to handle architecture-specific +aliasing of jp->entry. In the interest of portability, it is advised +to use: + + jp->entry = JPROBE_ENTRY(handler); + register_jprobe() returns 0 on success, or a negative errno otherwise. 4.3 register_kretprobe @@ -251,6 +272,11 @@ of interest: - ret_addr: the return address - rp: points to the corresponding kretprobe object - task: points to the corresponding task struct + +The get_retval(regs) macro provides a simple abstraction to extract +the return value from the appropriate register as defined by the +architecture's ABI. + The handler's return value is currently ignored. 4.4 unregister_*probe @@ -369,7 +395,6 @@ stack trace and selected i386 registers #include <linux/kernel.h> #include <linux/module.h> #include <linux/kprobes.h> -#include <linux/kallsyms.h> #include <linux/sched.h> /*For each probe you need to allocate a kprobe structure*/ @@ -403,18 +428,14 @@ int handler_fault(struct kprobe *p, stru return 0; } -int init_module(void) +static int __init kprobe_init(void) { int ret; kp.pre_handler = handler_pre; kp.post_handler = handler_post; kp.fault_handler = handler_fault; - kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork"); - /* register the kprobe now */ - if (!kp.addr) { - printk("Couldn't find %s to plant kprobe\n", "do_fork"); - return -1; - } + kp.symbol_name = "do_fork"; + if ((ret = register_kprobe(&kp) < 0)) { printk("register_kprobe failed, returned %d\n", ret); return -1; @@ -423,12 +444,14 @@ int init_module(void) return 0; } -void cleanup_module(void) +static void __exit kprobe_exit(void) { unregister_kprobe(&kp); printk("kprobe unregistered\n"); } +module_init(kprobe_init) +module_exit(kprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -463,7 +486,6 @@ the arguments of do_fork(). #include <linux/fs.h> #include <linux/uio.h> #include <linux/kprobes.h> -#include <linux/kallsyms.h> /* * Jumper probe for do_fork. @@ -485,17 +507,13 @@ long jdo_fork(unsigned long clone_flags, } static struct jprobe my_jprobe = { - .entry = (kprobe_opcode_t *) jdo_fork + .entry = JPROBE_ENTRY(jdo_fork) }; -int init_module(void) +static int __init jprobe_init(void) { int ret; - my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork"); - if (!my_jprobe.kp.addr) { - printk("Couldn't find %s to plant jprobe\n", "do_fork"); - return -1; - } + my_jprobe.kp.symbol_name = "do_fork"; if ((ret = register_jprobe(&my_jprobe)) <0) { printk("register_jprobe failed, returned %d\n", ret); @@ -506,12 +524,14 @@ int init_module(void) return 0; } -void cleanup_module(void) +static void __exit jprobe_exit(void) { unregister_jprobe(&my_jprobe); printk("jprobe unregistered\n"); } +module_init(jprobe_init) +module_exit(jprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -530,16 +550,13 @@ report failed calls to sys_open(). #include <linux/kernel.h> #include <linux/module.h> #include <linux/kprobes.h> -#include <linux/kallsyms.h> static const char *probed_func = "sys_open"; /* Return-probe handler: If the probed function fails, log the return value. */ static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { - // Substitute the appropriate register name for your architecture -- - // e.g., regs->rax for x86_64, regs->gpr[3] for ppc64. - int retval = (int) regs->eax; + int retval = get_retval(regs); if (retval < 0) { printk("%s returns %d\n", probed_func, retval); } @@ -552,15 +569,11 @@ static struct kretprobe my_kretprobe = { .maxactive = 20 }; -int init_module(void) +static int __init kretprobe_init(void) { int ret; - my_kretprobe.kp.addr = - (kprobe_opcode_t *) kallsyms_lookup_name(probed_func); - if (!my_kretprobe.kp.addr) { - printk("Couldn't find %s to plant return probe\n", probed_func); - return -1; - } + my_kretprobe.kp.symbol_name = (char *)probed_func; + if ((ret = register_kretprobe(&my_kretprobe)) < 0) { printk("register_kretprobe failed, returned %d\n", ret); return -1; @@ -569,7 +582,7 @@ int init_module(void) return 0; } -void cleanup_module(void) +static void __exit kretprobe_exit(void) { unregister_kretprobe(&my_kretprobe); printk("kretprobe unregistered\n"); @@ -578,6 +591,8 @@ void cleanup_module(void) my_kretprobe.nmissed, probed_func); } +module_init(kretprobe_init) +module_exit(kretprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -590,3 +605,5 @@ messages.) For additional information on Kprobes, refer to the following URLs: http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe http://www.redhat.com/magazine/005mar05/features/kprobes/ +http://www-users.cs.umn.edu/~boutcher/kprobes/ +http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 3/3] Kprobes: Update Documentation/kprobes.txt 2006-08-09 9:48 ` Ananth N Mavinakayanahalli @ 2006-08-09 10:24 ` Ananth N Mavinakayanahalli 0 siblings, 0 replies; 29+ messages in thread From: Ananth N Mavinakayanahalli @ 2006-08-09 10:24 UTC (permalink / raw) To: Christoph Hellwig, linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston On Wed, Aug 09, 2006 at 03:18:59PM +0530, Ananth N Mavinakayanahalli wrote: > On Tue, Aug 08, 2006 at 05:27:01PM +0100, Christoph Hellwig wrote: > > On Mon, Aug 07, 2006 at 05:34:47PM +0530, Ananth N Mavinakayanahalli wrote: > > > From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > > > > > > Update Documentation/kprobes.txt to reflect addition of KPROBE_ADDR, > > > KPROBE_RETVAL and the in-kernel symbol resolution. > > > > Thanks. With my updated patch we shouldn't document KPROBE_ADDR anymore > > but tell people to always use the symbol_name mechanisms. > Hopefully the final version :) Update Documentation/kprobes.txt: - Add usage details of "symbol_name" and "offset" fields of struct kprobe - Document return_value and JPROBE_ENTRY - Update references list - Update module examples to use module_init/module_exit interfaces Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> --- Documentation/kprobes.txt | 77 ++++++++++++++++++++++++++++------------------ 1 files changed, 47 insertions(+), 30 deletions(-) Index: linux-2.6.18-rc3/Documentation/kprobes.txt =================================================================== --- linux-2.6.18-rc3.orig/Documentation/kprobes.txt +++ linux-2.6.18-rc3/Documentation/kprobes.txt @@ -179,6 +179,21 @@ occurs during execution of kp->pre_handl or during single-stepping of the probed instruction, Kprobes calls kp->fault_handler. Any or all handlers can be NULL. +NOTE: +1. With the introduction of the "symbol_name" field to struct kprobe, +the probepoint address resolution will now be taken care of by the kernel. +The following will now work: + + kp.symbol_name = "symbol_name"; + +2. Use the "offset" field of struct kprobe if the offset into the symbol +to install a probepoint is known. This field is used to calculate the +probepoint address only if the "symbol_name" method of address resolution +is used. + +3. Specify either the kprobe "symbol_name" with "offset" OR the "addr". +If both are specified, kprobe registration will fail with -EINVAL. + register_kprobe() returns 0 on success, or a negative errno otherwise. User's pre-handler (kp->pre_handler): @@ -225,6 +240,12 @@ control to Kprobes.) If the probed func fastcall, or anything else that affects how args are passed, the handler's declaration must match. +NOTE: A macro JPROBE_ENTRY is provided to handle architecture-specific +aliasing of jp->entry. In the interest of portability, it is advised +to use: + + jp->entry = JPROBE_ENTRY(handler); + register_jprobe() returns 0 on success, or a negative errno otherwise. 4.3 register_kretprobe @@ -251,6 +272,11 @@ of interest: - ret_addr: the return address - rp: points to the corresponding kretprobe object - task: points to the corresponding task struct + +The return_value(regs) macro provides a simple abstraction to extract +the return value from the appropriate register as defined by the +architecture's ABI. + The handler's return value is currently ignored. 4.4 unregister_*probe @@ -369,7 +395,6 @@ stack trace and selected i386 registers #include <linux/kernel.h> #include <linux/module.h> #include <linux/kprobes.h> -#include <linux/kallsyms.h> #include <linux/sched.h> /*For each probe you need to allocate a kprobe structure*/ @@ -403,18 +428,14 @@ int handler_fault(struct kprobe *p, stru return 0; } -int init_module(void) +static int __init kprobe_init(void) { int ret; kp.pre_handler = handler_pre; kp.post_handler = handler_post; kp.fault_handler = handler_fault; - kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork"); - /* register the kprobe now */ - if (!kp.addr) { - printk("Couldn't find %s to plant kprobe\n", "do_fork"); - return -1; - } + kp.symbol_name = "do_fork"; + if ((ret = register_kprobe(&kp) < 0)) { printk("register_kprobe failed, returned %d\n", ret); return -1; @@ -423,12 +444,14 @@ int init_module(void) return 0; } -void cleanup_module(void) +static void __exit kprobe_exit(void) { unregister_kprobe(&kp); printk("kprobe unregistered\n"); } +module_init(kprobe_init) +module_exit(kprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -463,7 +486,6 @@ the arguments of do_fork(). #include <linux/fs.h> #include <linux/uio.h> #include <linux/kprobes.h> -#include <linux/kallsyms.h> /* * Jumper probe for do_fork. @@ -485,17 +507,13 @@ long jdo_fork(unsigned long clone_flags, } static struct jprobe my_jprobe = { - .entry = (kprobe_opcode_t *) jdo_fork + .entry = JPROBE_ENTRY(jdo_fork) }; -int init_module(void) +static int __init jprobe_init(void) { int ret; - my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork"); - if (!my_jprobe.kp.addr) { - printk("Couldn't find %s to plant jprobe\n", "do_fork"); - return -1; - } + my_jprobe.kp.symbol_name = "do_fork"; if ((ret = register_jprobe(&my_jprobe)) <0) { printk("register_jprobe failed, returned %d\n", ret); @@ -506,12 +524,14 @@ int init_module(void) return 0; } -void cleanup_module(void) +static void __exit jprobe_exit(void) { unregister_jprobe(&my_jprobe); printk("jprobe unregistered\n"); } +module_init(jprobe_init) +module_exit(jprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -530,16 +550,13 @@ report failed calls to sys_open(). #include <linux/kernel.h> #include <linux/module.h> #include <linux/kprobes.h> -#include <linux/kallsyms.h> static const char *probed_func = "sys_open"; /* Return-probe handler: If the probed function fails, log the return value. */ static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { - // Substitute the appropriate register name for your architecture -- - // e.g., regs->rax for x86_64, regs->gpr[3] for ppc64. - int retval = (int) regs->eax; + int retval = return_value(regs); if (retval < 0) { printk("%s returns %d\n", probed_func, retval); } @@ -552,15 +569,11 @@ static struct kretprobe my_kretprobe = { .maxactive = 20 }; -int init_module(void) +static int __init kretprobe_init(void) { int ret; - my_kretprobe.kp.addr = - (kprobe_opcode_t *) kallsyms_lookup_name(probed_func); - if (!my_kretprobe.kp.addr) { - printk("Couldn't find %s to plant return probe\n", probed_func); - return -1; - } + my_kretprobe.kp.symbol_name = (char *)probed_func; + if ((ret = register_kretprobe(&my_kretprobe)) < 0) { printk("register_kretprobe failed, returned %d\n", ret); return -1; @@ -569,7 +582,7 @@ int init_module(void) return 0; } -void cleanup_module(void) +static void __exit kretprobe_exit(void) { unregister_kretprobe(&my_kretprobe); printk("kretprobe unregistered\n"); @@ -578,6 +591,8 @@ void cleanup_module(void) my_kretprobe.nmissed, probed_func); } +module_init(kretprobe_init) +module_exit(kretprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -590,3 +605,5 @@ messages.) For additional information on Kprobes, refer to the following URLs: http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe http://www.redhat.com/magazine/005mar05/features/kprobes/ +http://www-users.cs.umn.edu/~boutcher/kprobes/ +http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/3] Kprobes: Define retval helper 2006-08-07 12:00 ` [PATCH 2/3] Kprobes: Define retval helper Ananth N Mavinakayanahalli 2006-08-07 12:04 ` [PATCH 3/3] Kprobes: Update Documentation/kprobes.txt Ananth N Mavinakayanahalli @ 2006-08-08 16:25 ` Christoph Hellwig 2006-08-09 4:37 ` Andi Kleen 2006-08-09 9:43 ` Ananth N Mavinakayanahalli 1 sibling, 2 replies; 29+ messages in thread From: Christoph Hellwig @ 2006-08-08 16:25 UTC (permalink / raw) To: Ananth N Mavinakayanahalli Cc: linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston On Mon, Aug 07, 2006 at 05:30:24PM +0530, Ananth N Mavinakayanahalli wrote: > From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > > Add the KPROBE_RETVAL macro to help extract the return value on > different architectures, while using function-return probes. Good idea. You should add parentheses around regs, otherwise the C preprocessor might bite users. Also the shouting name is quite ugly. In fact it should probably go to asm/system.h or similar and not have a kprobes name - it just extracts the return value from a struct pt_regs after all. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/3] Kprobes: Define retval helper 2006-08-08 16:25 ` [PATCH 2/3] Kprobes: Define retval helper Christoph Hellwig @ 2006-08-09 4:37 ` Andi Kleen 2006-08-09 9:43 ` Ananth N Mavinakayanahalli 1 sibling, 0 replies; 29+ messages in thread From: Andi Kleen @ 2006-08-09 4:37 UTC (permalink / raw) To: Christoph Hellwig Cc: linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston Christoph Hellwig <hch@infradead.org> writes: > On Mon, Aug 07, 2006 at 05:30:24PM +0530, Ananth N Mavinakayanahalli wrote: > > From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > > > > Add the KPROBE_RETVAL macro to help extract the return value on > > different architectures, while using function-return probes. > > Good idea. You should add parentheses around regs, otherwise the C > preprocessor might bite users. Also the shouting name is quite ugly. > In fact it should probably go to asm/system.h or similar The other macros like this (instruction_pointer etc) are in asm/ptrace.h -Andi ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/3] Kprobes: Define retval helper 2006-08-08 16:25 ` [PATCH 2/3] Kprobes: Define retval helper Christoph Hellwig 2006-08-09 4:37 ` Andi Kleen @ 2006-08-09 9:43 ` Ananth N Mavinakayanahalli 2006-08-09 9:45 ` Christoph Hellwig 1 sibling, 1 reply; 29+ messages in thread From: Ananth N Mavinakayanahalli @ 2006-08-09 9:43 UTC (permalink / raw) To: Christoph Hellwig, linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston On Tue, Aug 08, 2006 at 05:25:59PM +0100, Christoph Hellwig wrote: > On Mon, Aug 07, 2006 at 05:30:24PM +0530, Ananth N Mavinakayanahalli wrote: > > From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > > > > Add the KPROBE_RETVAL macro to help extract the return value on > > different architectures, while using function-return probes. > > Good idea. You should add parentheses around regs, otherwise the C > preprocessor might bite users. Also the shouting name is quite ugly. > In fact it should probably go to asm/system.h or similar and not have > a kprobes name - it just extracts the return value from a struct pt_regs > after all. Done! How does this look? I added it to asm/ptrace.h so it lives along with the instruction_pointer() definition. Ananth --- Add the "get_retval" macro that just extracts the return value given the pt_regs. Useful in situations such as while using function-return probes. Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> --- include/asm-i386/ptrace.h | 3 +++ include/asm-ia64/ptrace.h | 3 +++ include/asm-powerpc/ptrace.h | 2 ++ include/asm-x86_64/ptrace.h | 2 ++ 4 files changed, 10 insertions(+) Index: linux-2.6.18-rc3/include/asm-i386/ptrace.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-i386/ptrace.h +++ linux-2.6.18-rc3/include/asm-i386/ptrace.h @@ -79,7 +79,10 @@ static inline int user_mode_vm(struct pt { return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0; } + #define instruction_pointer(regs) ((regs)->eip) +#define get_retval(regs) ((regs)->eax) + #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) extern unsigned long profile_pc(struct pt_regs *regs); #else Index: linux-2.6.18-rc3/include/asm-ia64/ptrace.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-ia64/ptrace.h +++ linux-2.6.18-rc3/include/asm-ia64/ptrace.h @@ -237,6 +237,9 @@ struct switch_stack { * the canonical representation by adding to instruction pointer. */ # define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri) + +#define get_retval(regs) ((regs)->r8) + /* Conserve space in histogram by encoding slot bits in address * bits 2 and 3 rather than bits 0 and 1. */ Index: linux-2.6.18-rc3/include/asm-powerpc/ptrace.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-powerpc/ptrace.h +++ linux-2.6.18-rc3/include/asm-powerpc/ptrace.h @@ -73,6 +73,8 @@ struct pt_regs { #ifndef __ASSEMBLY__ #define instruction_pointer(regs) ((regs)->nip) +#define get_retval(regs) ((regs)->gpr[3]) + #ifdef CONFIG_SMP extern unsigned long profile_pc(struct pt_regs *regs); #else Index: linux-2.6.18-rc3/include/asm-x86_64/ptrace.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-x86_64/ptrace.h +++ linux-2.6.18-rc3/include/asm-x86_64/ptrace.h @@ -84,6 +84,8 @@ struct pt_regs { #define user_mode(regs) (!!((regs)->cs & 3)) #define user_mode_vm(regs) user_mode(regs) #define instruction_pointer(regs) ((regs)->rip) +#define get_retval(regs) ((regs)->rax) + extern unsigned long profile_pc(struct pt_regs *regs); void signal_fault(struct pt_regs *regs, void __user *frame, char *where); ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/3] Kprobes: Define retval helper 2006-08-09 9:43 ` Ananth N Mavinakayanahalli @ 2006-08-09 9:45 ` Christoph Hellwig 2006-08-09 9:55 ` Andi Kleen 2006-08-09 13:16 ` David Howells 0 siblings, 2 replies; 29+ messages in thread From: Christoph Hellwig @ 2006-08-09 9:45 UTC (permalink / raw) To: Ananth N Mavinakayanahalli Cc: Christoph Hellwig, linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston, linux-arch On Wed, Aug 09, 2006 at 03:13:11PM +0530, Ananth N Mavinakayanahalli wrote: > > Good idea. You should add parentheses around regs, otherwise the C > > preprocessor might bite users. Also the shouting name is quite ugly. > > In fact it should probably go to asm/system.h or similar and not have > > a kprobes name - it just extracts the return value from a struct pt_regs > > after all. > > Done! How does this look? I added it to asm/ptrace.h so it lives along > with the instruction_pointer() definition. Looks good, but it would be much better if we had it for every single architecture. I've cc'ed linux-arch so the arch maintainers can comments. Even if we don't manage to get every architecture maintainer to help out you should at least add sparc and s390 to have full coverage of architectures with kprobes support > Add the "get_retval" macro that just extracts the return value given the > pt_regs. Useful in situations such as while using function-return > probes. > > Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > > --- > include/asm-i386/ptrace.h | 3 +++ > include/asm-ia64/ptrace.h | 3 +++ > include/asm-powerpc/ptrace.h | 2 ++ > include/asm-x86_64/ptrace.h | 2 ++ > 4 files changed, 10 insertions(+) > > Index: linux-2.6.18-rc3/include/asm-i386/ptrace.h > =================================================================== > --- linux-2.6.18-rc3.orig/include/asm-i386/ptrace.h > +++ linux-2.6.18-rc3/include/asm-i386/ptrace.h > @@ -79,7 +79,10 @@ static inline int user_mode_vm(struct pt > { > return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0; > } > + > #define instruction_pointer(regs) ((regs)->eip) > +#define get_retval(regs) ((regs)->eax) > + > #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) > extern unsigned long profile_pc(struct pt_regs *regs); > #else > Index: linux-2.6.18-rc3/include/asm-ia64/ptrace.h > =================================================================== > --- linux-2.6.18-rc3.orig/include/asm-ia64/ptrace.h > +++ linux-2.6.18-rc3/include/asm-ia64/ptrace.h > @@ -237,6 +237,9 @@ struct switch_stack { > * the canonical representation by adding to instruction pointer. > */ > # define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri) > + > +#define get_retval(regs) ((regs)->r8) > + > /* Conserve space in histogram by encoding slot bits in address > * bits 2 and 3 rather than bits 0 and 1. > */ > Index: linux-2.6.18-rc3/include/asm-powerpc/ptrace.h > =================================================================== > --- linux-2.6.18-rc3.orig/include/asm-powerpc/ptrace.h > +++ linux-2.6.18-rc3/include/asm-powerpc/ptrace.h > @@ -73,6 +73,8 @@ struct pt_regs { > #ifndef __ASSEMBLY__ > > #define instruction_pointer(regs) ((regs)->nip) > +#define get_retval(regs) ((regs)->gpr[3]) > + > #ifdef CONFIG_SMP > extern unsigned long profile_pc(struct pt_regs *regs); > #else > Index: linux-2.6.18-rc3/include/asm-x86_64/ptrace.h > =================================================================== > --- linux-2.6.18-rc3.orig/include/asm-x86_64/ptrace.h > +++ linux-2.6.18-rc3/include/asm-x86_64/ptrace.h > @@ -84,6 +84,8 @@ struct pt_regs { > #define user_mode(regs) (!!((regs)->cs & 3)) > #define user_mode_vm(regs) user_mode(regs) > #define instruction_pointer(regs) ((regs)->rip) > +#define get_retval(regs) ((regs)->rax) > + > extern unsigned long profile_pc(struct pt_regs *regs); > void signal_fault(struct pt_regs *regs, void __user *frame, char *where); > ---end quoted text--- ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/3] Kprobes: Define retval helper 2006-08-09 9:45 ` Christoph Hellwig @ 2006-08-09 9:55 ` Andi Kleen 2006-08-09 10:19 ` Ananth N Mavinakayanahalli 2006-08-09 13:16 ` David Howells 1 sibling, 1 reply; 29+ messages in thread From: Andi Kleen @ 2006-08-09 9:55 UTC (permalink / raw) To: Christoph Hellwig Cc: Ananth N Mavinakayanahalli, linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston, linux-arch > > #define instruction_pointer(regs) ((regs)->eip) > > +#define get_retval(regs) ((regs)->eax) return_value() would match the names of the existing macro better -Andi ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/3] Kprobes: Define retval helper 2006-08-09 9:55 ` Andi Kleen @ 2006-08-09 10:19 ` Ananth N Mavinakayanahalli 2006-08-09 10:28 ` Martin Schwidefsky 0 siblings, 1 reply; 29+ messages in thread From: Ananth N Mavinakayanahalli @ 2006-08-09 10:19 UTC (permalink / raw) To: Andi Kleen Cc: Christoph Hellwig, linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston, linux-arch On Wed, Aug 09, 2006 at 11:55:50AM +0200, Andi Kleen wrote: > > > > #define instruction_pointer(regs) ((regs)->eip) > > > +#define get_retval(regs) ((regs)->eax) > > return_value() would match the names of the existing macro better Updated patch ... Add the "return_value" macro that just extracts the return value given the pt_regs. Useful in situations such as while using function-return probes. Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> --- include/asm-i386/ptrace.h | 3 +++ include/asm-ia64/ptrace.h | 3 +++ include/asm-powerpc/ptrace.h | 2 ++ include/asm-x86_64/ptrace.h | 2 ++ 4 files changed, 10 insertions(+) Index: linux-2.6.18-rc3/include/asm-i386/ptrace.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-i386/ptrace.h +++ linux-2.6.18-rc3/include/asm-i386/ptrace.h @@ -79,7 +79,10 @@ static inline int user_mode_vm(struct pt { return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0; } + #define instruction_pointer(regs) ((regs)->eip) +#define return_value(regs) ((regs)->eax) + #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) extern unsigned long profile_pc(struct pt_regs *regs); #else Index: linux-2.6.18-rc3/include/asm-ia64/ptrace.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-ia64/ptrace.h +++ linux-2.6.18-rc3/include/asm-ia64/ptrace.h @@ -237,6 +237,9 @@ struct switch_stack { * the canonical representation by adding to instruction pointer. */ # define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri) + +#define return_value(regs) ((regs)->r8) + /* Conserve space in histogram by encoding slot bits in address * bits 2 and 3 rather than bits 0 and 1. */ Index: linux-2.6.18-rc3/include/asm-powerpc/ptrace.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-powerpc/ptrace.h +++ linux-2.6.18-rc3/include/asm-powerpc/ptrace.h @@ -73,6 +73,8 @@ struct pt_regs { #ifndef __ASSEMBLY__ #define instruction_pointer(regs) ((regs)->nip) +#define return_value(regs) ((regs)->gpr[3]) + #ifdef CONFIG_SMP extern unsigned long profile_pc(struct pt_regs *regs); #else Index: linux-2.6.18-rc3/include/asm-x86_64/ptrace.h =================================================================== --- linux-2.6.18-rc3.orig/include/asm-x86_64/ptrace.h +++ linux-2.6.18-rc3/include/asm-x86_64/ptrace.h @@ -84,6 +84,8 @@ struct pt_regs { #define user_mode(regs) (!!((regs)->cs & 3)) #define user_mode_vm(regs) user_mode(regs) #define instruction_pointer(regs) ((regs)->rip) +#define return_value(regs) ((regs)->rax) + extern unsigned long profile_pc(struct pt_regs *regs); void signal_fault(struct pt_regs *regs, void __user *frame, char *where); ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/3] Kprobes: Define retval helper 2006-08-09 10:19 ` Ananth N Mavinakayanahalli @ 2006-08-09 10:28 ` Martin Schwidefsky 0 siblings, 0 replies; 29+ messages in thread From: Martin Schwidefsky @ 2006-08-09 10:28 UTC (permalink / raw) To: ananth Cc: Andi Kleen, Christoph Hellwig, linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston, linux-arch On Wed, 2006-08-09 at 15:49 +0530, Ananth N Mavinakayanahalli wrote: > Updated patch ... > > Add the "return_value" macro that just extracts the return value given > the pt_regs. Useful in situations such as while using function-return > probes. return_value definition for s390 see below. -- blue skies, Martin. Martin Schwidefsky Linux for zSeries Development & Services IBM Deutschland Entwicklung GmbH "Reality continues to ruin my life." - Calvin. --- diff -urpN linux-2.6.18-rc3/include/asm-s390/ptrace.h linux-2.6.18-s390/include/asm-s390/ptrace.h --- linux-2.6.18-rc3/include/asm-s390/ptrace.h 2006-06-29 12:47:32.000000000 +0200 +++ linux-2.6.18-s390/include/asm-s390/ptrace.h 2006-08-09 12:25:23.000000000 +0200 @@ -472,6 +472,7 @@ struct user_regs_struct #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) +#define return_value(regs)((regs)->gprs[2]) #define profile_pc(regs) instruction_pointer(regs) extern void show_regs(struct pt_regs * regs); #endif ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/3] Kprobes: Define retval helper 2006-08-09 9:45 ` Christoph Hellwig 2006-08-09 9:55 ` Andi Kleen @ 2006-08-09 13:16 ` David Howells 2006-08-09 15:20 ` Ananth N Mavinakayanahalli 1 sibling, 1 reply; 29+ messages in thread From: David Howells @ 2006-08-09 13:16 UTC (permalink / raw) To: Christoph Hellwig Cc: Ananth N Mavinakayanahalli, linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston, linux-arch Christoph Hellwig <hch@infradead.org> wrote: > > > Good idea. You should add parentheses around regs, otherwise the C > > > preprocessor might bite users. Also the shouting name is quite ugly. > > > In fact it should probably go to asm/system.h or similar and not have > > > a kprobes name - it just extracts the return value from a struct pt_regs > > > after all. > > > > Done! How does this look? I added it to asm/ptrace.h so it lives along > > with the instruction_pointer() definition. I presume we don't care about return values that span multiple registers - for instance if you return a 64-bit value on i386 it'll wind up in EDX:EAX. David ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/3] Kprobes: Define retval helper 2006-08-09 13:16 ` David Howells @ 2006-08-09 15:20 ` Ananth N Mavinakayanahalli 0 siblings, 0 replies; 29+ messages in thread From: Ananth N Mavinakayanahalli @ 2006-08-09 15:20 UTC (permalink / raw) To: David Howells Cc: Christoph Hellwig, linux-kernel, Prasanna S Panchamukhi, Anil S Keshavamurthy, Jim Keniston, linux-arch On Wed, Aug 09, 2006 at 02:16:04PM +0100, David Howells wrote: > Christoph Hellwig <hch@infradead.org> wrote: > > > > > Good idea. You should add parentheses around regs, otherwise the C > > > > preprocessor might bite users. Also the shouting name is quite ugly. > > > > In fact it should probably go to asm/system.h or similar and not have > > > > a kprobes name - it just extracts the return value from a struct pt_regs > > > > after all. > > > > > > Done! How does this look? I added it to asm/ptrace.h so it lives along > > > with the instruction_pointer() definition. > > I presume we don't care about return values that span multiple registers - for > instance if you return a 64-bit value on i386 it'll wind up in EDX:EAX. Yes. This helper is mostly to address the common case, not the 64-bit one. Ananth ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-07 11:55 [PATCH 1/3] Kprobes: Make kprobe modules more portable Ananth N Mavinakayanahalli 2006-08-07 12:00 ` [PATCH 2/3] Kprobes: Define retval helper Ananth N Mavinakayanahalli @ 2006-08-07 12:06 ` Ananth N Mavinakayanahalli 2006-08-08 16:24 ` Christoph Hellwig 2 siblings, 0 replies; 29+ messages in thread From: Ananth N Mavinakayanahalli @ 2006-08-07 12:06 UTC (permalink / raw) To: linux-kernel On Mon, Aug 07, 2006 at 05:25:37PM +0530, Ananth N Mavinakayanahalli wrote: > From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > > This patch introduces KPROBE_ADDR, a macro that abstracts out the > architecture-specific artefacts of getting the correct text address > given a symbol. While we are at it, also introduce the symbol_name field > in struct kprobe to allow for users to just specify the address to be > probed in terms of the kernel symbol. In-kernel kprobes infrastructure > decodes the actual text address to probe. The symbol resolution happens > only if the kprobe.addr isn't explicitly specified. This change was first mooted by Dave Boutcher during his kprobes tutorial @ OLS. Thanks Dave! (He had also signed off on the patch) > > --- > Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > Signed-off-by: Prasanna S.P <prasanna@in.ibm.com> Acked-by: Dave Boutcher <sleddog@us.ibm.com> > > > --- > include/asm-powerpc/kprobes.h | 2 ++ > include/linux/kprobes.h | 8 ++++++++ > kernel/kprobes.c | 4 ++++ > 3 files changed, 14 insertions(+) > > Index: linux-2.6.18-rc3/include/asm-powerpc/kprobes.h > =================================================================== > --- linux-2.6.18-rc3.orig/include/asm-powerpc/kprobes.h > +++ linux-2.6.18-rc3/include/asm-powerpc/kprobes.h > @@ -44,6 +44,8 @@ typedef unsigned int kprobe_opcode_t; > #define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000) > #define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000) > > +#define KPROBE_ADDR(name) *((kprobe_opcode_t **)(kallsyms_lookup_name(name))) > + > #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry) > > #define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \ > Index: linux-2.6.18-rc3/include/linux/kprobes.h > =================================================================== > --- linux-2.6.18-rc3.orig/include/linux/kprobes.h > +++ linux-2.6.18-rc3/include/linux/kprobes.h > @@ -36,6 +36,7 @@ > #include <linux/spinlock.h> > #include <linux/rcupdate.h> > #include <linux/mutex.h> > +#include <linux/kallsyms.h> > > #ifdef CONFIG_KPROBES > #include <asm/kprobes.h> > @@ -49,6 +50,10 @@ > /* Attach to insert probes on any functions which should be ignored*/ > #define __kprobes __attribute__((__section__(".kprobes.text"))) > > +#ifndef KPROBE_ADDR /* powerpc has its own definition */ > +#define KPROBE_ADDR(name) (kprobe_opcode_t *)(kallsyms_lookup_name(name)) > +#endif /* KPROBE_ADDR */ > + > struct kprobe; > struct pt_regs; > struct kretprobe; > @@ -77,6 +82,9 @@ struct kprobe { > /* location of the probe point */ > kprobe_opcode_t *addr; > > + /* Allow user to indicate symbol name of the probe point */ > + char *symbol_name; > + > /* Called before addr is executed. */ > kprobe_pre_handler_t pre_handler; > > Index: linux-2.6.18-rc3/kernel/kprobes.c > =================================================================== > --- linux-2.6.18-rc3.orig/kernel/kprobes.c > +++ linux-2.6.18-rc3/kernel/kprobes.c > @@ -446,6 +446,10 @@ static int __kprobes __register_kprobe(s > struct kprobe *old_p; > struct module *probed_mod; > > + /* Do the kallsyms lookup only if p->addr == NULL */ > + if (!p->addr && (p->symbol_name)) > + p->addr = KPROBE_ADDR(p->symbol_name); > + > if ((!kernel_text_address((unsigned long) p->addr)) || > in_kprobes_functions((unsigned long) p->addr)) > return -EINVAL; ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-07 11:55 [PATCH 1/3] Kprobes: Make kprobe modules more portable Ananth N Mavinakayanahalli 2006-08-07 12:00 ` [PATCH 2/3] Kprobes: Define retval helper Ananth N Mavinakayanahalli 2006-08-07 12:06 ` [PATCH 1/3] Kprobes: Make kprobe modules more portable Ananth N Mavinakayanahalli @ 2006-08-08 16:24 ` Christoph Hellwig 2006-08-08 16:34 ` Stephen Hemminger ` (2 more replies) 2 siblings, 3 replies; 29+ messages in thread From: Christoph Hellwig @ 2006-08-08 16:24 UTC (permalink / raw) To: Ananth N Mavinakayanahalli; +Cc: linux-kernel, shemminger On Mon, Aug 07, 2006 at 05:25:37PM +0530, Ananth N Mavinakayanahalli wrote: > From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > > This patch introduces KPROBE_ADDR, a macro that abstracts out the > architecture-specific artefacts of getting the correct text address > given a symbol. While we are at it, also introduce the symbol_name field > in struct kprobe to allow for users to just specify the address to be > probed in terms of the kernel symbol. In-kernel kprobes infrastructure > decodes the actual text address to probe. The symbol resolution happens > only if the kprobe.addr isn't explicitly specified. This looks good. A few issues are left: - the KPROBE_ADDR macro is all uppercase and not exactly very descriptive. - the symbol name variant should be the default, and no one outside kprobes.c should know about the KPROBE_ADDR macro - we should return EINVAL instead of silently discarding things if people specify a symbol and an address. - we should have and offset into the symbol specified The updated patch below does that, aswell as updating the only inkernel kprobes user (tcp_probe.c) to the new interface (*) and removing the now obsolete kallsysms_lookup_name export. (*) tcp_probe.c shows very well how horrible the old interface was, as it's not portable to ppc64 as-is Signed-off-by: Christoph Hellwig <hch@lst.de> Index: linux-2.6/include/asm-powerpc/kprobes.h =================================================================== --- linux-2.6.orig/include/asm-powerpc/kprobes.h 2006-08-08 17:47:22.000000000 +0200 +++ linux-2.6/include/asm-powerpc/kprobes.h 2006-08-08 18:13:57.000000000 +0200 @@ -44,6 +44,9 @@ #define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000) #define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000) +#define kprobe_lookup_name(name) \ + (*((kprobe_opcode_t **)kallsyms_lookup_name(name))) + #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry) #define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \ Index: linux-2.6/include/linux/kprobes.h =================================================================== --- linux-2.6.orig/include/linux/kprobes.h 2006-08-08 17:47:22.000000000 +0200 +++ linux-2.6/include/linux/kprobes.h 2006-08-08 17:47:31.000000000 +0200 @@ -77,6 +77,12 @@ /* location of the probe point */ kprobe_opcode_t *addr; + /* Allow user to indicate symbol name of the probe point */ + char *symbol_name; + + /* Offset into the symbol */ + unsigned int offset; + /* Called before addr is executed. */ kprobe_pre_handler_t pre_handler; Index: linux-2.6/kernel/kprobes.c =================================================================== --- linux-2.6.orig/kernel/kprobes.c 2006-08-08 17:47:22.000000000 +0200 +++ linux-2.6/kernel/kprobes.c 2006-08-08 17:47:31.000000000 +0200 @@ -37,6 +37,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/moduleloader.h> +#include <linux/kallsyms.h> #include <asm-generic/sections.h> #include <asm/cacheflush.h> #include <asm/errno.h> @@ -45,6 +46,16 @@ #define KPROBE_HASH_BITS 6 #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS) + +/* + * Some oddball architectures like 64bit powerpc have function descriptors + * so this must be overridable. + */ +#ifndef kprobe_lookup_name +#define kprobe_lookup_name(name) \ + ((kprobe_opcode_t *)(kallsyms_lookup_name(name)) +#endif + static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE]; static atomic_t kprobe_count; @@ -447,6 +458,17 @@ struct kprobe *old_p; struct module *probed_mod; + /* + * If we have a symbol_name argument look it up, + * and add it to the address. That way the addr + * field can either be global or relative to a symbol. + */ + if (p->symbol_name) { + if (p->addr) + return -EINVAL; + p->addr = kprobe_lookup_name(p->symbol_name) + p->offset; + } + if ((!kernel_text_address((unsigned long) p->addr)) || in_kprobes_functions((unsigned long) p->addr)) return -EINVAL; Index: linux-2.6/kernel/kallsyms.c =================================================================== --- linux-2.6.orig/kernel/kallsyms.c 2006-08-08 17:13:14.000000000 +0200 +++ linux-2.6/kernel/kallsyms.c 2006-08-08 17:47:39.000000000 +0200 @@ -154,7 +154,6 @@ } return module_kallsyms_lookup_name(name); } -EXPORT_SYMBOL_GPL(kallsyms_lookup_name); /* * Lookup an address Index: linux-2.6/net/ipv4/tcp_probe.c =================================================================== --- linux-2.6.orig/net/ipv4/tcp_probe.c 2006-08-08 18:13:55.000000000 +0200 +++ linux-2.6/net/ipv4/tcp_probe.c 2006-08-08 18:14:28.000000000 +0200 @@ -99,8 +99,10 @@ } static struct jprobe tcp_send_probe = { - .kp = { .addr = (kprobe_opcode_t *) &tcp_sendmsg, }, - .entry = (kprobe_opcode_t *) &jtcp_sendmsg, + .kp = { + .symbol_name = "tcp_sendmsg", + }, + .entry = JPROBE_ENTRY(jtcp_sendmsg), }; ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-08 16:24 ` Christoph Hellwig @ 2006-08-08 16:34 ` Stephen Hemminger 2006-08-08 16:40 ` Christoph Hellwig 2006-08-09 9:51 ` Ananth N Mavinakayanahalli 2006-08-09 16:01 ` David Smith 2 siblings, 1 reply; 29+ messages in thread From: Stephen Hemminger @ 2006-08-08 16:34 UTC (permalink / raw) To: Christoph Hellwig; +Cc: Ananth N Mavinakayanahalli, linux-kernel On Tue, 8 Aug 2006 17:24:21 +0100 Christoph Hellwig <hch@infradead.org> wrote: > On Mon, Aug 07, 2006 at 05:25:37PM +0530, Ananth N Mavinakayanahalli wrote: > > From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > > > > This patch introduces KPROBE_ADDR, a macro that abstracts out the > > architecture-specific artefacts of getting the correct text address > > given a symbol. While we are at it, also introduce the symbol_name field > > in struct kprobe to allow for users to just specify the address to be > > probed in terms of the kernel symbol. In-kernel kprobes infrastructure > > decodes the actual text address to probe. The symbol resolution happens > > only if the kprobe.addr isn't explicitly specified. > > This looks good. A few issues are left: > > - the KPROBE_ADDR macro is all uppercase and not exactly very descriptive. > - the symbol name variant should be the default, and no one outside > kprobes.c should know about the KPROBE_ADDR macro > - we should return EINVAL instead of silently discarding things if people > specify a symbol and an address. > - we should have and offset into the symbol specified > > The updated patch below does that, aswell as updating the only inkernel > kprobes user (tcp_probe.c) to the new interface (*) and removing the now > obsolete kallsysms_lookup_name export. > > (*) tcp_probe.c shows very well how horrible the old interface was, as it's > not portable to ppc64 as-is Okay, does this makes kprobe's the first reflective kernel interface. Watch out or it end up like JNI! ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-08 16:34 ` Stephen Hemminger @ 2006-08-08 16:40 ` Christoph Hellwig 2006-08-08 17:28 ` Paulo Marques 0 siblings, 1 reply; 29+ messages in thread From: Christoph Hellwig @ 2006-08-08 16:40 UTC (permalink / raw) To: Stephen Hemminger Cc: Christoph Hellwig, Ananth N Mavinakayanahalli, linux-kernel On Tue, Aug 08, 2006 at 09:34:00AM -0700, Stephen Hemminger wrote: > Okay, does this makes kprobe's the first reflective kernel interface. Actually kallsyms_lookup_name was the first interface like that. And lots of external kprobes used it like that - in fact tcp_probe.c is the first one I've seen doing it differently. But kallsyms_lookup_name is a really awkward lowlevel buildingblock that's almost impossible to use correctly, so this patch hides it behind the proper kprobes interface. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-08 16:40 ` Christoph Hellwig @ 2006-08-08 17:28 ` Paulo Marques 2006-08-08 17:32 ` Christoph Hellwig 0 siblings, 1 reply; 29+ messages in thread From: Paulo Marques @ 2006-08-08 17:28 UTC (permalink / raw) To: Christoph Hellwig, Stephen Hemminger, Ananth N Mavinakayanahalli, linux-kernel Christoph Hellwig wrote: > On Tue, Aug 08, 2006 at 09:34:00AM -0700, Stephen Hemminger wrote: >> Okay, does this makes kprobe's the first reflective kernel interface. > > Actually kallsyms_lookup_name was the first interface like that. And lots > of external kprobes used it like that - in fact tcp_probe.c is the first > one I've seen doing it differently. But kallsyms_lookup_name is a really > awkward lowlevel buildingblock that's almost impossible to use correctly, > so this patch hides it behind the proper kprobes interface. Just one side note: kallsyms_lookup_name is _really_ inefficient. The kallsyms structure is tailored so that kallsyms_lookup (the most frequently used function) is really fast. Doing it the other way around involves a O(N) search, uncompressing every symbol name as it goes :P I don't think this is really a performance problem for users like kprobes, but I just wanted people to keep in mind that there is a penalty involved in calling kallsyms_lookup_name. -- Paulo Marques - www.grupopie.com "The face of a child can say it all, especially the mouth part of the face." ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-08 17:28 ` Paulo Marques @ 2006-08-08 17:32 ` Christoph Hellwig 0 siblings, 0 replies; 29+ messages in thread From: Christoph Hellwig @ 2006-08-08 17:32 UTC (permalink / raw) To: Paulo Marques Cc: Christoph Hellwig, Stephen Hemminger, Ananth N Mavinakayanahalli, linux-kernel On Tue, Aug 08, 2006 at 06:28:28PM +0100, Paulo Marques wrote: > Just one side note: kallsyms_lookup_name is _really_ inefficient. The > kallsyms structure is tailored so that kallsyms_lookup (the most > frequently used function) is really fast. Doing it the other way around > involves a O(N) search, uncompressing every symbol name as it goes :P > > I don't think this is really a performance problem for users like > kprobes, but I just wanted people to keep in mind that there is a > penalty involved in calling kallsyms_lookup_name. That's true. One more reason to not expose this interface to the public. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-08 16:24 ` Christoph Hellwig 2006-08-08 16:34 ` Stephen Hemminger @ 2006-08-09 9:51 ` Ananth N Mavinakayanahalli 2006-08-09 16:01 ` David Smith 2 siblings, 0 replies; 29+ messages in thread From: Ananth N Mavinakayanahalli @ 2006-08-09 9:51 UTC (permalink / raw) To: Christoph Hellwig, linux-kernel, shemminger On Tue, Aug 08, 2006 at 05:24:21PM +0100, Christoph Hellwig wrote: > On Mon, Aug 07, 2006 at 05:25:37PM +0530, Ananth N Mavinakayanahalli wrote: > > From: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > > > > This patch introduces KPROBE_ADDR, a macro that abstracts out the > > architecture-specific artefacts of getting the correct text address > > given a symbol. While we are at it, also introduce the symbol_name field > > in struct kprobe to allow for users to just specify the address to be > > probed in terms of the kernel symbol. In-kernel kprobes infrastructure > > decodes the actual text address to probe. The symbol resolution happens > > only if the kprobe.addr isn't explicitly specified. > > This looks good. A few issues are left: > > - the KPROBE_ADDR macro is all uppercase and not exactly very descriptive. > - the symbol name variant should be the default, and no one outside > kprobes.c should know about the KPROBE_ADDR macro > - we should return EINVAL instead of silently discarding things if people > specify a symbol and an address. > - we should have and offset into the symbol specified Agreed. > The updated patch below does that, aswell as updating the only inkernel > kprobes user (tcp_probe.c) to the new interface (*) and removing the now > obsolete kallsysms_lookup_name export. > > (*) tcp_probe.c shows very well how horrible the old interface was, as it's > not portable to ppc64 as-is > > Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> > Index: linux-2.6/include/asm-powerpc/kprobes.h > =================================================================== > --- linux-2.6.orig/include/asm-powerpc/kprobes.h 2006-08-08 17:47:22.000000000 +0200 > +++ linux-2.6/include/asm-powerpc/kprobes.h 2006-08-08 18:13:57.000000000 +0200 > @@ -44,6 +44,9 @@ > #define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000) > #define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000) > > +#define kprobe_lookup_name(name) \ > + (*((kprobe_opcode_t **)kallsyms_lookup_name(name))) > + > #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry) > > #define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \ > Index: linux-2.6/include/linux/kprobes.h > =================================================================== > --- linux-2.6.orig/include/linux/kprobes.h 2006-08-08 17:47:22.000000000 +0200 > +++ linux-2.6/include/linux/kprobes.h 2006-08-08 17:47:31.000000000 +0200 > @@ -77,6 +77,12 @@ > /* location of the probe point */ > kprobe_opcode_t *addr; > > + /* Allow user to indicate symbol name of the probe point */ > + char *symbol_name; > + > + /* Offset into the symbol */ > + unsigned int offset; > + > /* Called before addr is executed. */ > kprobe_pre_handler_t pre_handler; > > Index: linux-2.6/kernel/kprobes.c > =================================================================== > --- linux-2.6.orig/kernel/kprobes.c 2006-08-08 17:47:22.000000000 +0200 > +++ linux-2.6/kernel/kprobes.c 2006-08-08 17:47:31.000000000 +0200 > @@ -37,6 +37,7 @@ > #include <linux/slab.h> > #include <linux/module.h> > #include <linux/moduleloader.h> > +#include <linux/kallsyms.h> > #include <asm-generic/sections.h> > #include <asm/cacheflush.h> > #include <asm/errno.h> > @@ -45,6 +46,16 @@ > #define KPROBE_HASH_BITS 6 > #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS) > > + > +/* > + * Some oddball architectures like 64bit powerpc have function descriptors > + * so this must be overridable. > + */ > +#ifndef kprobe_lookup_name > +#define kprobe_lookup_name(name) \ > + ((kprobe_opcode_t *)(kallsyms_lookup_name(name)) > +#endif > + > static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; > static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE]; > static atomic_t kprobe_count; > @@ -447,6 +458,17 @@ > struct kprobe *old_p; > struct module *probed_mod; > > + /* > + * If we have a symbol_name argument look it up, > + * and add it to the address. That way the addr > + * field can either be global or relative to a symbol. > + */ > + if (p->symbol_name) { > + if (p->addr) > + return -EINVAL; > + p->addr = kprobe_lookup_name(p->symbol_name) + p->offset; > + } > + > if ((!kernel_text_address((unsigned long) p->addr)) || > in_kprobes_functions((unsigned long) p->addr)) > return -EINVAL; > Index: linux-2.6/kernel/kallsyms.c > =================================================================== > --- linux-2.6.orig/kernel/kallsyms.c 2006-08-08 17:13:14.000000000 +0200 > +++ linux-2.6/kernel/kallsyms.c 2006-08-08 17:47:39.000000000 +0200 > @@ -154,7 +154,6 @@ > } > return module_kallsyms_lookup_name(name); > } > -EXPORT_SYMBOL_GPL(kallsyms_lookup_name); > > /* > * Lookup an address > Index: linux-2.6/net/ipv4/tcp_probe.c > =================================================================== > --- linux-2.6.orig/net/ipv4/tcp_probe.c 2006-08-08 18:13:55.000000000 +0200 > +++ linux-2.6/net/ipv4/tcp_probe.c 2006-08-08 18:14:28.000000000 +0200 > @@ -99,8 +99,10 @@ > } > > static struct jprobe tcp_send_probe = { > - .kp = { .addr = (kprobe_opcode_t *) &tcp_sendmsg, }, > - .entry = (kprobe_opcode_t *) &jtcp_sendmsg, > + .kp = { > + .symbol_name = "tcp_sendmsg", > + }, > + .entry = JPROBE_ENTRY(jtcp_sendmsg), > }; > > ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-08 16:24 ` Christoph Hellwig 2006-08-08 16:34 ` Stephen Hemminger 2006-08-09 9:51 ` Ananth N Mavinakayanahalli @ 2006-08-09 16:01 ` David Smith 2006-08-09 16:10 ` Christoph Hellwig 2 siblings, 1 reply; 29+ messages in thread From: David Smith @ 2006-08-09 16:01 UTC (permalink / raw) To: Christoph Hellwig; +Cc: Ananth N Mavinakayanahalli, linux-kernel, shemminger On Tue, 2006-08-08 at 17:24 +0100, Christoph Hellwig wrote: > On Mon, Aug 07, 2006 at 05:25:37PM +0530, Ananth N Mavinakayanahalli wrote: ... stuff deleted ... > > + /* > + * If we have a symbol_name argument look it up, > + * and add it to the address. That way the addr > + * field can either be global or relative to a symbol. > + */ > + if (p->symbol_name) { > + if (p->addr) > + return -EINVAL; > + p->addr = kprobe_lookup_name(p->symbol_name) + p->offset; > + } What if kprobe_lookup_name() fails or if CONFIG_KALLSYMS isn't set? The code following this might work, but the kprobe isn't going to be set at the location that was intended. Perhaps this needs something like: if (p->symbol_name) { if (p->addr) return -EINVAL; p->addr = kprobe_lookup_name(p->symbol_name) + p->offset; if (p->addr == p->offset) return -EINVAL; } -- David Smith dsmith@redhat.com Red Hat, Inc. http://www.redhat.com 256.217.0141 (direct) 256.837.0057 (fax) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-09 16:01 ` David Smith @ 2006-08-09 16:10 ` Christoph Hellwig 2006-08-09 16:18 ` Christoph Hellwig 2006-08-10 6:18 ` Ananth N Mavinakayanahalli 0 siblings, 2 replies; 29+ messages in thread From: Christoph Hellwig @ 2006-08-09 16:10 UTC (permalink / raw) To: David Smith Cc: Christoph Hellwig, Ananth N Mavinakayanahalli, linux-kernel, shemminger On Wed, Aug 09, 2006 at 11:01:45AM -0500, David Smith wrote: > > + if (p->symbol_name) { > > + if (p->addr) > > + return -EINVAL; > > + p->addr = kprobe_lookup_name(p->symbol_name) + p->offset; > > + } > > What if kprobe_lookup_name() fails for that case we need the check in your snipplet below. > or if CONFIG_KALLSYMS isn't set? I think we should just disallow that case. having kprobes without kallsyms is rather pointless. I'll send a patch to add the dependency to the Kconfig files. > Perhaps this needs something like: > > if (p->symbol_name) { > if (p->addr) > return -EINVAL; > p->addr = kprobe_lookup_name(p->symbol_name) + p->offset; > if (p->addr == p->offset) > return -EINVAL; > } ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-09 16:10 ` Christoph Hellwig @ 2006-08-09 16:18 ` Christoph Hellwig 2006-08-10 14:10 ` Keshavamurthy Anil S 2006-08-11 8:53 ` Ananth N Mavinakayanahalli 2006-08-10 6:18 ` Ananth N Mavinakayanahalli 1 sibling, 2 replies; 29+ messages in thread From: Christoph Hellwig @ 2006-08-09 16:18 UTC (permalink / raw) To: Christoph Hellwig, David Smith, Ananth N Mavinakayanahalli, linux-kernel, shemminger On Wed, Aug 09, 2006 at 05:10:39PM +0100, Christoph Hellwig wrote: > On Wed, Aug 09, 2006 at 11:01:45AM -0500, David Smith wrote: > > > + if (p->symbol_name) { > > > + if (p->addr) > > > + return -EINVAL; > > > + p->addr = kprobe_lookup_name(p->symbol_name) + p->offset; > > > + } > > > > What if kprobe_lookup_name() fails > > for that case we need the check in your snipplet below. > > > or if CONFIG_KALLSYMS isn't set? > > I think we should just disallow that case. having kprobes without kallsyms > is rather pointless. I'll send a patch to add the dependency to the Kconfig > files. Here's an updated version of that patch that a) adds a KALLYMS dependency and b) adds a check for p->addr. Note that this check is outside the if (p->symbol_name) block so it also returns EINVAL if the user didn't specifcy either and address or a symbol name. Index: linux-2.6/include/asm-powerpc/kprobes.h =================================================================== --- linux-2.6.orig/include/asm-powerpc/kprobes.h 2006-08-09 13:44:39.000000000 +0200 +++ linux-2.6/include/asm-powerpc/kprobes.h 2006-08-09 13:44:57.000000000 +0200 @@ -44,6 +44,9 @@ #define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000) #define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000) +#define kprobe_lookup_name(name) \ + (*((kprobe_opcode_t **)kallsyms_lookup_name(name))) + #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry) #define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \ Index: linux-2.6/include/linux/kprobes.h =================================================================== --- linux-2.6.orig/include/linux/kprobes.h 2006-08-09 13:44:39.000000000 +0200 +++ linux-2.6/include/linux/kprobes.h 2006-08-09 13:44:57.000000000 +0200 @@ -77,6 +77,12 @@ /* location of the probe point */ kprobe_opcode_t *addr; + /* Allow user to indicate symbol name of the probe point */ + char *symbol_name; + + /* Offset into the symbol */ + unsigned int offset; + /* Called before addr is executed. */ kprobe_pre_handler_t pre_handler; Index: linux-2.6/kernel/kprobes.c =================================================================== --- linux-2.6.orig/kernel/kprobes.c 2006-08-09 13:44:39.000000000 +0200 +++ linux-2.6/kernel/kprobes.c 2006-08-09 18:12:47.000000000 +0200 @@ -37,6 +37,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/moduleloader.h> +#include <linux/kallsyms.h> #include <asm-generic/sections.h> #include <asm/cacheflush.h> #include <asm/errno.h> @@ -45,6 +46,16 @@ #define KPROBE_HASH_BITS 6 #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS) + +/* + * Some oddball architectures like 64bit powerpc have function descriptors + * so this must be overridable. + */ +#ifndef kprobe_lookup_name +#define kprobe_lookup_name(name) \ + ((kprobe_opcode_t *)(kallsyms_lookup_name(name)) +#endif + static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE]; static atomic_t kprobe_count; @@ -447,6 +458,21 @@ struct kprobe *old_p; struct module *probed_mod; + /* + * If we have a symbol_name argument look it up, + * and add it to the address. That way the addr + * field can either be global or relative to a symbol. + */ + if (p->symbol_name) { + if (p->addr) + return -EINVAL; + p->addr = kprobe_lookup_name(p->symbol_name); + } + + if (!p->addr) + return -EINVAL; + p->addr += p->offset; + if ((!kernel_text_address((unsigned long) p->addr)) || in_kprobes_functions((unsigned long) p->addr)) return -EINVAL; Index: linux-2.6/kernel/kallsyms.c =================================================================== --- linux-2.6.orig/kernel/kallsyms.c 2006-08-09 13:44:39.000000000 +0200 +++ linux-2.6/kernel/kallsyms.c 2006-08-09 13:44:57.000000000 +0200 @@ -154,7 +154,6 @@ } return module_kallsyms_lookup_name(name); } -EXPORT_SYMBOL_GPL(kallsyms_lookup_name); /* * Lookup an address Index: linux-2.6/net/ipv4/tcp_probe.c =================================================================== --- linux-2.6.orig/net/ipv4/tcp_probe.c 2006-08-09 13:44:39.000000000 +0200 +++ linux-2.6/net/ipv4/tcp_probe.c 2006-08-09 13:44:57.000000000 +0200 @@ -99,8 +99,10 @@ } static struct jprobe tcp_send_probe = { - .kp = { .addr = (kprobe_opcode_t *) &tcp_sendmsg, }, - .entry = (kprobe_opcode_t *) &jtcp_sendmsg, + .kp = { + .symbol_name = "tcp_sendmsg", + }, + .entry = JPROBE_ENTRY(jtcp_sendmsg), }; Index: linux-2.6/arch/i386/Kconfig =================================================================== --- linux-2.6.orig/arch/i386/Kconfig 2006-08-08 17:13:13.000000000 +0200 +++ linux-2.6/arch/i386/Kconfig 2006-08-09 18:13:59.000000000 +0200 @@ -1129,7 +1129,7 @@ config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes Index: linux-2.6/arch/ia64/Kconfig =================================================================== --- linux-2.6.orig/arch/ia64/Kconfig 2006-08-08 17:13:13.000000000 +0200 +++ linux-2.6/arch/ia64/Kconfig 2006-08-09 18:14:13.000000000 +0200 @@ -510,7 +510,7 @@ config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes Index: linux-2.6/arch/powerpc/Kconfig =================================================================== --- linux-2.6.orig/arch/powerpc/Kconfig 2006-08-08 17:13:13.000000000 +0200 +++ linux-2.6/arch/powerpc/Kconfig 2006-08-09 18:15:00.000000000 +0200 @@ -1045,7 +1045,7 @@ config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on PPC64 && EXPERIMENTAL && MODULES + depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes Index: linux-2.6/arch/sparc64/Kconfig =================================================================== --- linux-2.6.orig/arch/sparc64/Kconfig 2006-08-08 17:13:13.000000000 +0200 +++ linux-2.6/arch/sparc64/Kconfig 2006-08-09 18:14:42.000000000 +0200 @@ -416,7 +416,7 @@ config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes Index: linux-2.6/arch/x86_64/Kconfig =================================================================== --- linux-2.6.orig/arch/x86_64/Kconfig 2006-08-08 17:13:13.000000000 +0200 +++ linux-2.6/arch/x86_64/Kconfig 2006-08-09 18:14:27.000000000 +0200 @@ -639,7 +639,7 @@ config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-09 16:18 ` Christoph Hellwig @ 2006-08-10 14:10 ` Keshavamurthy Anil S 2006-08-16 13:20 ` Christoph Hellwig 2006-08-11 8:53 ` Ananth N Mavinakayanahalli 1 sibling, 1 reply; 29+ messages in thread From: Keshavamurthy Anil S @ 2006-08-10 14:10 UTC (permalink / raw) To: Christoph Hellwig, David Smith, Ananth N Mavinakayanahalli, linux-kernel, shemminger On Wed, Aug 09, 2006 at 05:18:54PM +0100, Christoph Hellwig wrote: > + */ > + if (p->symbol_name) { > + if (p->addr) > + return -EINVAL; > + p->addr = kprobe_lookup_name(p->symbol_name); > + } > + > + if (!p->addr) > + return -EINVAL; > + p->addr += p->offset; This should be p->addr = (kprobe_opcode_t *)(((char *)p->addr) + p->offset), since p->addr is of type pointer to kprobe_opcode_t and the size of kprobe_opcode_t is different for different architecture. At least for ia64 this p->addr type is not a pointer to char. -Anil Keshavamurthy ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-10 14:10 ` Keshavamurthy Anil S @ 2006-08-16 13:20 ` Christoph Hellwig 0 siblings, 0 replies; 29+ messages in thread From: Christoph Hellwig @ 2006-08-16 13:20 UTC (permalink / raw) To: Keshavamurthy Anil S Cc: Christoph Hellwig, David Smith, Ananth N Mavinakayanahalli, linux-kernel, shemminger On Thu, Aug 10, 2006 at 07:10:29AM -0700, Keshavamurthy Anil S wrote: > This should be p->addr = (kprobe_opcode_t *)(((char *)p->addr) + p->offset), since p->addr is of type > pointer to kprobe_opcode_t and the size of kprobe_opcode_t is different for different > architecture. At least for ia64 this p->addr type is not a pointer to char. Similarly for powerpc. We should either put this change in or drop the offset into symbol support until actual users pop up.. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-09 16:18 ` Christoph Hellwig 2006-08-10 14:10 ` Keshavamurthy Anil S @ 2006-08-11 8:53 ` Ananth N Mavinakayanahalli 1 sibling, 0 replies; 29+ messages in thread From: Ananth N Mavinakayanahalli @ 2006-08-11 8:53 UTC (permalink / raw) To: Christoph Hellwig, David Smith, linux-kernel, shemminger On Wed, Aug 09, 2006 at 05:18:54PM +0100, Christoph Hellwig wrote: > On Wed, Aug 09, 2006 at 05:10:39PM +0100, Christoph Hellwig wrote: > > On Wed, Aug 09, 2006 at 11:01:45AM -0500, David Smith wrote: > > > > + if (p->symbol_name) { > > > > + if (p->addr) > > > > + return -EINVAL; > > > > + p->addr = kprobe_lookup_name(p->symbol_name) + p->offset; > > > > + } > > > > > > What if kprobe_lookup_name() fails > > > > for that case we need the check in your snipplet below. > > > > > or if CONFIG_KALLSYMS isn't set? > > > > I think we should just disallow that case. having kprobes without kallsyms > > is rather pointless. I'll send a patch to add the dependency to the Kconfig > > files. > > Here's an updated version of that patch that a) adds a KALLYMS dependency > and b) adds a check for p->addr. Note that this check is outside the > if (p->symbol_name) block so it also returns EINVAL if the user didn't > specifcy either and address or a symbol name. ... > > Index: linux-2.6/kernel/kprobes.c > =================================================================== > --- linux-2.6.orig/kernel/kprobes.c 2006-08-09 13:44:39.000000000 +0200 > +++ linux-2.6/kernel/kprobes.c 2006-08-09 18:12:47.000000000 +0200 > @@ -37,6 +37,7 @@ > #include <linux/slab.h> > #include <linux/module.h> > #include <linux/moduleloader.h> > +#include <linux/kallsyms.h> > #include <asm-generic/sections.h> > #include <asm/cacheflush.h> > #include <asm/errno.h> > @@ -45,6 +46,16 @@ > #define KPROBE_HASH_BITS 6 > #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS) > > + > +/* > + * Some oddball architectures like 64bit powerpc have function descriptors > + * so this must be overridable. > + */ > +#ifndef kprobe_lookup_name > +#define kprobe_lookup_name(name) \ > + ((kprobe_opcode_t *)(kallsyms_lookup_name(name)) This is missing a ')'. Updated patch below... Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> --- arch/i386/Kconfig | 2 +- arch/ia64/Kconfig | 2 +- arch/powerpc/Kconfig | 2 +- arch/sparc64/Kconfig | 2 +- arch/x86_64/Kconfig | 2 +- include/asm-powerpc/kprobes.h | 3 +++ include/linux/kprobes.h | 6 ++++++ kernel/kallsyms.c | 1 - kernel/kprobes.c | 26 ++++++++++++++++++++++++++ net/ipv4/tcp_probe.c | 6 ++++-- 10 files changed, 44 insertions(+), 8 deletions(-) Index: linux-2.6.18-rc4/arch/i386/Kconfig =================================================================== --- linux-2.6.18-rc4.orig/arch/i386/Kconfig +++ linux-2.6.18-rc4/arch/i386/Kconfig @@ -1129,7 +1129,7 @@ source "arch/i386/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes Index: linux-2.6.18-rc4/arch/ia64/Kconfig =================================================================== --- linux-2.6.18-rc4.orig/arch/ia64/Kconfig +++ linux-2.6.18-rc4/arch/ia64/Kconfig @@ -510,7 +510,7 @@ source "arch/ia64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes Index: linux-2.6.18-rc4/arch/powerpc/Kconfig =================================================================== --- linux-2.6.18-rc4.orig/arch/powerpc/Kconfig +++ linux-2.6.18-rc4/arch/powerpc/Kconfig @@ -1045,7 +1045,7 @@ source "arch/powerpc/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on PPC64 && EXPERIMENTAL && MODULES + depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes Index: linux-2.6.18-rc4/arch/sparc64/Kconfig =================================================================== --- linux-2.6.18-rc4.orig/arch/sparc64/Kconfig +++ linux-2.6.18-rc4/arch/sparc64/Kconfig @@ -416,7 +416,7 @@ source "arch/sparc64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes Index: linux-2.6.18-rc4/arch/x86_64/Kconfig =================================================================== --- linux-2.6.18-rc4.orig/arch/x86_64/Kconfig +++ linux-2.6.18-rc4/arch/x86_64/Kconfig @@ -639,7 +639,7 @@ source "arch/x86_64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on EXPERIMENTAL && MODULES + depends on KALLSYMS && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes Index: linux-2.6.18-rc4/include/asm-powerpc/kprobes.h =================================================================== --- linux-2.6.18-rc4.orig/include/asm-powerpc/kprobes.h +++ linux-2.6.18-rc4/include/asm-powerpc/kprobes.h @@ -44,6 +44,9 @@ typedef unsigned int kprobe_opcode_t; #define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000) #define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000) +#define kprobe_lookup_name(name) \ + (*((kprobe_opcode_t **)kallsyms_lookup_name(name))) + #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)((func_descr_t *)pentry) #define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \ Index: linux-2.6.18-rc4/include/linux/kprobes.h =================================================================== --- linux-2.6.18-rc4.orig/include/linux/kprobes.h +++ linux-2.6.18-rc4/include/linux/kprobes.h @@ -77,6 +77,12 @@ struct kprobe { /* location of the probe point */ kprobe_opcode_t *addr; + /* Allow user to indicate symbol name of the probe point */ + char *symbol_name; + + /* Offset into the symbol */ + unsigned int offset; + /* Called before addr is executed. */ kprobe_pre_handler_t pre_handler; Index: linux-2.6.18-rc4/kernel/kallsyms.c =================================================================== --- linux-2.6.18-rc4.orig/kernel/kallsyms.c +++ linux-2.6.18-rc4/kernel/kallsyms.c @@ -154,7 +154,6 @@ unsigned long kallsyms_lookup_name(const } return module_kallsyms_lookup_name(name); } -EXPORT_SYMBOL_GPL(kallsyms_lookup_name); /* * Lookup an address Index: linux-2.6.18-rc4/kernel/kprobes.c =================================================================== --- linux-2.6.18-rc4.orig/kernel/kprobes.c +++ linux-2.6.18-rc4/kernel/kprobes.c @@ -37,6 +37,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/moduleloader.h> +#include <linux/kallsyms.h> #include <asm-generic/sections.h> #include <asm/cacheflush.h> #include <asm/errno.h> @@ -45,6 +46,16 @@ #define KPROBE_HASH_BITS 6 #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS) + +/* + * Some oddball architectures like 64bit powerpc have function descriptors + * so this must be overridable. + */ +#ifndef kprobe_lookup_name +#define kprobe_lookup_name(name) \ + ((kprobe_opcode_t *)(kallsyms_lookup_name(name))) +#endif + static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE]; static atomic_t kprobe_count; @@ -447,6 +458,21 @@ static int __kprobes __register_kprobe(s struct kprobe *old_p; struct module *probed_mod; + /* + * If we have a symbol_name argument look it up, + * and add it to the address. That way the addr + * field can either be global or relative to a symbol. + */ + if (p->symbol_name) { + if (p->addr) + return -EINVAL; + p->addr = kprobe_lookup_name(p->symbol_name); + } + + if (!p->addr) + return -EINVAL; + p->addr += p->offset; + if ((!kernel_text_address((unsigned long) p->addr)) || in_kprobes_functions((unsigned long) p->addr)) return -EINVAL; Index: linux-2.6.18-rc4/net/ipv4/tcp_probe.c =================================================================== --- linux-2.6.18-rc4.orig/net/ipv4/tcp_probe.c +++ linux-2.6.18-rc4/net/ipv4/tcp_probe.c @@ -99,8 +99,10 @@ static int jtcp_sendmsg(struct kiocb *io } static struct jprobe tcp_send_probe = { - .kp = { .addr = (kprobe_opcode_t *) &tcp_sendmsg, }, - .entry = (kprobe_opcode_t *) &jtcp_sendmsg, + .kp = { + .symbol_name = "tcp_sendmsg", + }, + .entry = JPROBE_ENTRY(jtcp_sendmsg), }; ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/3] Kprobes: Make kprobe modules more portable 2006-08-09 16:10 ` Christoph Hellwig 2006-08-09 16:18 ` Christoph Hellwig @ 2006-08-10 6:18 ` Ananth N Mavinakayanahalli 1 sibling, 0 replies; 29+ messages in thread From: Ananth N Mavinakayanahalli @ 2006-08-10 6:18 UTC (permalink / raw) To: Christoph Hellwig, David Smith, linux-kernel, shemminger On Wed, Aug 09, 2006 at 05:10:39PM +0100, Christoph Hellwig wrote: > On Wed, Aug 09, 2006 at 11:01:45AM -0500, David Smith wrote: > > > + if (p->symbol_name) { > > > + if (p->addr) > > > + return -EINVAL; > > > + p->addr = kprobe_lookup_name(p->symbol_name) + p->offset; > > > + } > > > > What if kprobe_lookup_name() fails > > for that case we need the check in your snipplet below. The next check: if ((!kernel_text_address((unsigned long) p->addr)) || in_kprobes_functions((unsigned long) p->addr)) return -EINVAL; will catch this case anyway (unless some arch has kernel text starting at vaddr 0) Ananth > > > or if CONFIG_KALLSYMS isn't set? > > I think we should just disallow that case. having kprobes without kallsyms > is rather pointless. I'll send a patch to add the dependency to the Kconfig > files. > > > Perhaps this needs something like: > > > > if (p->symbol_name) { > > if (p->addr) > > return -EINVAL; > > p->addr = kprobe_lookup_name(p->symbol_name) + p->offset; > > if (p->addr == p->offset) > > return -EINVAL; > > } ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2006-08-16 13:21 UTC | newest] Thread overview: 29+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-08-07 11:55 [PATCH 1/3] Kprobes: Make kprobe modules more portable Ananth N Mavinakayanahalli 2006-08-07 12:00 ` [PATCH 2/3] Kprobes: Define retval helper Ananth N Mavinakayanahalli 2006-08-07 12:04 ` [PATCH 3/3] Kprobes: Update Documentation/kprobes.txt Ananth N Mavinakayanahalli 2006-08-08 16:27 ` Christoph Hellwig 2006-08-09 9:48 ` Ananth N Mavinakayanahalli 2006-08-09 10:24 ` Ananth N Mavinakayanahalli 2006-08-08 16:25 ` [PATCH 2/3] Kprobes: Define retval helper Christoph Hellwig 2006-08-09 4:37 ` Andi Kleen 2006-08-09 9:43 ` Ananth N Mavinakayanahalli 2006-08-09 9:45 ` Christoph Hellwig 2006-08-09 9:55 ` Andi Kleen 2006-08-09 10:19 ` Ananth N Mavinakayanahalli 2006-08-09 10:28 ` Martin Schwidefsky 2006-08-09 13:16 ` David Howells 2006-08-09 15:20 ` Ananth N Mavinakayanahalli 2006-08-07 12:06 ` [PATCH 1/3] Kprobes: Make kprobe modules more portable Ananth N Mavinakayanahalli 2006-08-08 16:24 ` Christoph Hellwig 2006-08-08 16:34 ` Stephen Hemminger 2006-08-08 16:40 ` Christoph Hellwig 2006-08-08 17:28 ` Paulo Marques 2006-08-08 17:32 ` Christoph Hellwig 2006-08-09 9:51 ` Ananth N Mavinakayanahalli 2006-08-09 16:01 ` David Smith 2006-08-09 16:10 ` Christoph Hellwig 2006-08-09 16:18 ` Christoph Hellwig 2006-08-10 14:10 ` Keshavamurthy Anil S 2006-08-16 13:20 ` Christoph Hellwig 2006-08-11 8:53 ` Ananth N Mavinakayanahalli 2006-08-10 6:18 ` Ananth N Mavinakayanahalli
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox