| .. | .. |
|---|
| 453 | 453 | struct pt_regs *regs) |
|---|
| 454 | 454 | { |
|---|
| 455 | 455 | ri->ret_addr = (kprobe_opcode_t *)(regs->u_regs[UREG_RETPC] + 8); |
|---|
| 456 | + ri->fp = NULL; |
|---|
| 456 | 457 | |
|---|
| 457 | 458 | /* Replace the return addr with trampoline addr */ |
|---|
| 458 | 459 | regs->u_regs[UREG_RETPC] = |
|---|
| .. | .. |
|---|
| 465 | 466 | static int __kprobes trampoline_probe_handler(struct kprobe *p, |
|---|
| 466 | 467 | struct pt_regs *regs) |
|---|
| 467 | 468 | { |
|---|
| 468 | | - struct kretprobe_instance *ri = NULL; |
|---|
| 469 | | - struct hlist_head *head, empty_rp; |
|---|
| 470 | | - struct hlist_node *tmp; |
|---|
| 471 | | - unsigned long flags, orig_ret_address = 0; |
|---|
| 472 | | - unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; |
|---|
| 469 | + unsigned long orig_ret_address = 0; |
|---|
| 473 | 470 | |
|---|
| 474 | | - INIT_HLIST_HEAD(&empty_rp); |
|---|
| 475 | | - kretprobe_hash_lock(current, &head, &flags); |
|---|
| 476 | | - |
|---|
| 477 | | - /* |
|---|
| 478 | | - * It is possible to have multiple instances associated with a given |
|---|
| 479 | | - * task either because an multiple functions in the call path |
|---|
| 480 | | - * have a return probe installed on them, and/or more than one return |
|---|
| 481 | | - * return probe was registered for a target function. |
|---|
| 482 | | - * |
|---|
| 483 | | - * We can handle this because: |
|---|
| 484 | | - * - instances are always inserted at the head of the list |
|---|
| 485 | | - * - when multiple return probes are registered for the same |
|---|
| 486 | | - * function, the first instance's ret_addr will point to the |
|---|
| 487 | | - * real return address, and all the rest will point to |
|---|
| 488 | | - * kretprobe_trampoline |
|---|
| 489 | | - */ |
|---|
| 490 | | - hlist_for_each_entry_safe(ri, tmp, head, hlist) { |
|---|
| 491 | | - if (ri->task != current) |
|---|
| 492 | | - /* another task is sharing our hash bucket */ |
|---|
| 493 | | - continue; |
|---|
| 494 | | - |
|---|
| 495 | | - if (ri->rp && ri->rp->handler) |
|---|
| 496 | | - ri->rp->handler(ri, regs); |
|---|
| 497 | | - |
|---|
| 498 | | - orig_ret_address = (unsigned long)ri->ret_addr; |
|---|
| 499 | | - recycle_rp_inst(ri, &empty_rp); |
|---|
| 500 | | - |
|---|
| 501 | | - if (orig_ret_address != trampoline_address) |
|---|
| 502 | | - /* |
|---|
| 503 | | - * This is the real return address. Any other |
|---|
| 504 | | - * instances associated with this task are for |
|---|
| 505 | | - * other calls deeper on the call stack |
|---|
| 506 | | - */ |
|---|
| 507 | | - break; |
|---|
| 508 | | - } |
|---|
| 509 | | - |
|---|
| 510 | | - kretprobe_assert(ri, orig_ret_address, trampoline_address); |
|---|
| 471 | + orig_ret_address = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL); |
|---|
| 511 | 472 | regs->tpc = orig_ret_address; |
|---|
| 512 | 473 | regs->tnpc = orig_ret_address + 4; |
|---|
| 513 | 474 | |
|---|
| 514 | | - kretprobe_hash_unlock(current, &flags); |
|---|
| 515 | | - |
|---|
| 516 | | - hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { |
|---|
| 517 | | - hlist_del(&ri->hlist); |
|---|
| 518 | | - kfree(ri); |
|---|
| 519 | | - } |
|---|
| 520 | 475 | /* |
|---|
| 521 | 476 | * By returning a non-zero value, we are telling |
|---|
| 522 | 477 | * kprobe_handler() that we don't want the post_handler |
|---|