aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kprobes.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kprobes.c')
-rw-r--r--kernel/kprobes.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 7a86e6432338..fcfb580c3afc 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -498,27 +498,36 @@ static int __kprobes in_kprobes_functions(unsigned long addr)
498 return 0; 498 return 0;
499} 499}
500 500
501/*
502 * If we have a symbol_name argument, look it up and add the offset field
503 * to it. This way, we can specify a relative address to a symbol.
504 */
505static kprobe_opcode_t __kprobes *kprobe_addr(struct kprobe *p)
506{
507 kprobe_opcode_t *addr = p->addr;
508 if (p->symbol_name) {
509 if (addr)
510 return NULL;
511 kprobe_lookup_name(p->symbol_name, addr);
512 }
513
514 if (!addr)
515 return NULL;
516 return (kprobe_opcode_t *)(((char *)addr) + p->offset);
517}
518
501static int __kprobes __register_kprobe(struct kprobe *p, 519static int __kprobes __register_kprobe(struct kprobe *p,
502 unsigned long called_from) 520 unsigned long called_from)
503{ 521{
504 int ret = 0; 522 int ret = 0;
505 struct kprobe *old_p; 523 struct kprobe *old_p;
506 struct module *probed_mod; 524 struct module *probed_mod;
525 kprobe_opcode_t *addr;
507 526
508 /* 527 addr = kprobe_addr(p);
509 * If we have a symbol_name argument look it up, 528 if (!addr)
510 * and add it to the address. That way the addr
511 * field can either be global or relative to a symbol.
512 */
513 if (p->symbol_name) {
514 if (p->addr)
515 return -EINVAL;
516 kprobe_lookup_name(p->symbol_name, p->addr);
517 }
518
519 if (!p->addr)
520 return -EINVAL; 529 return -EINVAL;
521 p->addr = (kprobe_opcode_t *)(((char *)p->addr)+ p->offset); 530 p->addr = addr;
522 531
523 if (!kernel_text_address((unsigned long) p->addr) || 532 if (!kernel_text_address((unsigned long) p->addr) ||
524 in_kprobes_functions((unsigned long) p->addr)) 533 in_kprobes_functions((unsigned long) p->addr))
@@ -678,8 +687,7 @@ void __kprobes unregister_jprobe(struct jprobe *jp)
678 unregister_kprobe(&jp->kp); 687 unregister_kprobe(&jp->kp);
679} 688}
680 689
681#ifdef ARCH_SUPPORTS_KRETPROBES 690#ifdef CONFIG_KRETPROBES
682
683/* 691/*
684 * This kprobe pre_handler is registered with every kretprobe. When probe 692 * This kprobe pre_handler is registered with every kretprobe. When probe
685 * hits it will set up the return probe. 693 * hits it will set up the return probe.
@@ -722,12 +730,12 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
722 int ret = 0; 730 int ret = 0;
723 struct kretprobe_instance *inst; 731 struct kretprobe_instance *inst;
724 int i; 732 int i;
725 void *addr = rp->kp.addr; 733 void *addr;
726 734
727 if (kretprobe_blacklist_size) { 735 if (kretprobe_blacklist_size) {
728 if (addr == NULL) 736 addr = kprobe_addr(&rp->kp);
729 kprobe_lookup_name(rp->kp.symbol_name, addr); 737 if (!addr)
730 addr += rp->kp.offset; 738 return -EINVAL;
731 739
732 for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { 740 for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
733 if (kretprobe_blacklist[i].addr == addr) 741 if (kretprobe_blacklist[i].addr == addr)
@@ -769,8 +777,7 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
769 return ret; 777 return ret;
770} 778}
771 779
772#else /* ARCH_SUPPORTS_KRETPROBES */ 780#else /* CONFIG_KRETPROBES */
773
774int __kprobes register_kretprobe(struct kretprobe *rp) 781int __kprobes register_kretprobe(struct kretprobe *rp)
775{ 782{
776 return -ENOSYS; 783 return -ENOSYS;
@@ -781,8 +788,7 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p,
781{ 788{
782 return 0; 789 return 0;
783} 790}
784 791#endif /* CONFIG_KRETPROBES */
785#endif /* ARCH_SUPPORTS_KRETPROBES */
786 792
787void __kprobes unregister_kretprobe(struct kretprobe *rp) 793void __kprobes unregister_kretprobe(struct kretprobe *rp)
788{ 794{