{
struct us_ip *ip = container_of(ri->rp, struct us_ip, retprobe);
unsigned long addr = (unsigned long)ip->retprobe.up.kp.addr;
+ unsigned long ret_addr = ri->ret_addr;
#if defined(CONFIG_ARM)
addr = ip->offset & 0x01 ? addr | 0x01 : addr;
#endif
- exit_event(regs, addr);
+ exit_event(regs, addr, ret_addr);
return 0;
}
u32 pid;
u32 tid;
u64 pc_addr;
+ u64 caller_pc_addr;
u32 cpu_num;
u64 ret_val;
} __attribute__((packed));
-static char *pack_msg_func_exit(char *payload, struct pt_regs *regs, unsigned long func_addr)
+static char *pack_msg_func_exit(char *payload, struct pt_regs *regs,
+ unsigned long func_addr,
+ unsigned long ret_addr)
{
struct msg_func_exit *mfe = (struct msg_func_exit *)payload;
struct task_struct *task = current;
mfe->tid = task->pid;
mfe->cpu_num = task_cpu(task);
mfe->pc_addr = func_addr;
+ mfe->caller_pc_addr = ret_addr;
mfe->ret_val = get_regs_ret_val(regs);
return payload + sizeof(*mfe);
}
-int exit_event(struct pt_regs *regs, unsigned long func_addr)
+int exit_event(struct pt_regs *regs, unsigned long func_addr,
+ unsigned long ret_addr)
{
char *buf, *payload, *buf_end;
buf = get_current_buf();
payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_EXIT);
- buf_end = pack_msg_func_exit(payload, regs, func_addr);
+ buf_end = pack_msg_func_exit(payload, regs, func_addr, ret_addr);
set_len_msg(buf, buf_end);
return write_to_buffer(buf);
int entry_event(const char *fmt, struct pt_regs *regs,
enum PROBE_TYPE pt, int sub_type);
-int exit_event(struct pt_regs *regs, unsigned long func_addr);
+int exit_event(struct pt_regs *regs, unsigned long func_addr,
+ unsigned long ret_addr);
int switch_entry(struct pt_regs *regs);
int switch_exit(struct pt_regs *regs);