Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 94111
b: refs/heads/master
c: 26b31c1
h: refs/heads/master
i:
  94109: 8c9d6bd
  94107: 1e5e666
  94103: 026541a
  94095: 49b0b7f
  94079: 1cfee4f
v: v3
  • Loading branch information
Masami Hiramatsu authored and Linus Torvalds committed Apr 28, 2008
1 parent 1cf3b75 commit bac4e81
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4a296e07c3a410c09b9155da4c2fa84a07964f38
refs/heads/master: 26b31c1908e02a316edfba08080373342e662c14
9 changes: 9 additions & 0 deletions trunk/include/linux/kprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ int setjmp_pre_handler(struct kprobe *, struct pt_regs *);
int longjmp_break_handler(struct kprobe *, struct pt_regs *);
int register_jprobe(struct jprobe *p);
void unregister_jprobe(struct jprobe *p);
int register_jprobes(struct jprobe **jps, int num);
void unregister_jprobes(struct jprobe **jps, int num);
void jprobe_return(void);
unsigned long arch_deref_entry_point(void *);

Expand Down Expand Up @@ -279,9 +281,16 @@ static inline int register_jprobe(struct jprobe *p)
{
return -ENOSYS;
}
static inline int register_jprobes(struct jprobe **jps, int num)
{
return -ENOSYS;
}
static inline void unregister_jprobe(struct jprobe *p)
{
}
static inline void unregister_jprobes(struct jprobe **jps, int num)
{
}
static inline void jprobe_return(void)
{
}
Expand Down
65 changes: 56 additions & 9 deletions trunk/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,24 +755,69 @@ unsigned long __weak arch_deref_entry_point(void *entry)
return (unsigned long)entry;
}

int __kprobes register_jprobe(struct jprobe *jp)
static int __register_jprobes(struct jprobe **jps, int num,
unsigned long called_from)
{
unsigned long addr = arch_deref_entry_point(jp->entry);
struct jprobe *jp;
int ret = 0, i;

if (!kernel_text_address(addr))
if (num <= 0)
return -EINVAL;
for (i = 0; i < num; i++) {
unsigned long addr;
jp = jps[i];
addr = arch_deref_entry_point(jp->entry);

if (!kernel_text_address(addr))
ret = -EINVAL;
else {
/* Todo: Verify probepoint is a function entry point */
jp->kp.pre_handler = setjmp_pre_handler;
jp->kp.break_handler = longjmp_break_handler;
ret = __register_kprobe(&jp->kp, called_from);
}
if (ret < 0 && i > 0) {
unregister_jprobes(jps, i);
break;
}
}
return ret;
}

/* Todo: Verify probepoint is a function entry point */
jp->kp.pre_handler = setjmp_pre_handler;
jp->kp.break_handler = longjmp_break_handler;

return __register_kprobe(&jp->kp,
int __kprobes register_jprobe(struct jprobe *jp)
{
return __register_jprobes(&jp, 1,
(unsigned long)__builtin_return_address(0));
}

void __kprobes unregister_jprobe(struct jprobe *jp)
{
unregister_kprobe(&jp->kp);
unregister_jprobes(&jp, 1);
}

int __kprobes register_jprobes(struct jprobe **jps, int num)
{
return __register_jprobes(jps, num,
(unsigned long)__builtin_return_address(0));
}

void __kprobes unregister_jprobes(struct jprobe **jps, int num)
{
int i;

if (num <= 0)
return;
mutex_lock(&kprobe_mutex);
for (i = 0; i < num; i++)
if (__unregister_kprobe_top(&jps[i]->kp) < 0)
jps[i]->kp.addr = NULL;
mutex_unlock(&kprobe_mutex);

synchronize_sched();
for (i = 0; i < num; i++) {
if (jps[i]->kp.addr)
__unregister_kprobe_bottom(&jps[i]->kp);
}
}

#ifdef CONFIG_KRETPROBES
Expand Down Expand Up @@ -1236,6 +1281,8 @@ EXPORT_SYMBOL_GPL(register_kprobes);
EXPORT_SYMBOL_GPL(unregister_kprobes);
EXPORT_SYMBOL_GPL(register_jprobe);
EXPORT_SYMBOL_GPL(unregister_jprobe);
EXPORT_SYMBOL_GPL(register_jprobes);
EXPORT_SYMBOL_GPL(unregister_jprobes);
#ifdef CONFIG_KPROBES
EXPORT_SYMBOL_GPL(jprobe_return);
#endif
Expand Down

0 comments on commit bac4e81

Please sign in to comment.