#include "us_proc_inst.h"
#include "../kprobe/dbi_kprobes_deps.h"
-#include "../kprobe/dbi_uprobes.h"
+#include "../uprobe/swap_uprobes.h"
#include "sspt/sspt.h"
-#include "java_inst.h"
+
+#include <dbi_insn_slots.h>
#define mm_read_lock(task, mm, atomic, lock) \
mm = atomic ? task->active_mm : get_task_mm(task); \
mmput(mm); \
}
-#if defined(CONFIG_MIPS)
-# define ARCH_REG_VAL(regs, idx) regs->regs[idx]
-#elif defined(CONFIG_ARM)
-# define ARCH_REG_VAL(regs, idx) regs->uregs[idx]
-#else
-# define ARCH_REG_VAL(regs, idx) 0
-# warning ARCH_REG_VAL is not implemented for this architecture. FBI will work improperly or even crash!!!
-#endif // ARCH
-
unsigned long ujprobe_event_pre_handler (struct us_ip *ip, struct pt_regs *regs);
void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6);
-int uretprobe_event_handler (struct kretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip);
+int uretprobe_event_handler(struct uretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip);
-int us_proc_probes;
-
LIST_HEAD(proc_probes_list);
-
-#ifdef ANDROID_APP
-unsigned long android_app_vma_start = 0;
-unsigned long android_app_vma_end = 0;
-struct dentry *app_process_dentry = NULL;
-#endif /* ANDROID_APP */
-
-#ifdef SLP_APP
-static struct dentry *launchpad_daemon_dentry = NULL;
-EXPORT_SYMBOL_GPL(launchpad_daemon_dentry);
-#endif /* SLP_APP */
-
#define print_event(fmt, args...) \
{ \
char *buf[1024]; \
return !!us_proc_info.path;
}
+static unsigned long alloc_user_pages(struct task_struct *task, unsigned long len, unsigned long prot, unsigned long flags)
+{
+ unsigned long ret = 0;
+ struct task_struct *otask = current;
+ struct mm_struct *mm;
+ int atomic = in_atomic();
+
+ mm = atomic ? task->active_mm : get_task_mm (task);
+ if (mm) {
+ if (!atomic) {
+ if (!down_write_trylock(&mm->mmap_sem)) {
+ rcu_read_lock();
+
+ up_read(&mm->mmap_sem);
+ down_write(&mm->mmap_sem);
+
+ rcu_read_unlock();
+ }
+ }
+ // FIXME: its seems to be bad decision to replace 'current' pointer temporarily
+ current_thread_info()->task = task;
+ ret = do_mmap_pgoff(NULL, 0, len, prot, flags, 0);
+ current_thread_info()->task = otask;
+ if (!atomic) {
+ downgrade_write (&mm->mmap_sem);
+ mmput(mm);
+ }
+ } else {
+ printk("proc %d has no mm", task->tgid);
+ }
+
+ return ret;
+}
+
+static void *sm_alloc_us(struct slot_manager *sm)
+{
+ struct task_struct *task = sm->data;
+
+ return (void *)alloc_user_pages(task, PAGE_SIZE,
+ PROT_EXEC|PROT_READ|PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE);
+}
+
+static void sm_free_us(struct slot_manager *sm, void *ptr)
+{
+ struct task_struct *task = sm->data;
+
+ /*
+ * E. G.: This code provides kernel dump because of rescheduling while atomic.
+ * As workaround, this code was commented. In this case we will have memory leaks
+ * for instrumented process, but instrumentation process should functionate correctly.
+ * Planned that good solution for this problem will be done during redesigning KProbe
+ * for improving supportability and performance.
+ */
+#if 0
+ mm = get_task_mm(task);
+ if (mm) {
+ down_write(&mm->mmap_sem);
+ do_munmap(mm, (unsigned long)(ptr), PAGE_SIZE);
+ up_write(&mm->mmap_sem);
+ mmput(mm);
+ }
+#endif
+ /* FIXME: implement the removal of memory for task */
+}
+
+struct slot_manager *create_sm_us(struct task_struct *task)
+{
+ struct slot_manager *sm = kmalloc(sizeof(*sm), GFP_ATOMIC);
+ sm->slot_size = UPROBES_TRAMP_LEN;
+ sm->alloc = sm_alloc_us;
+ sm->free = sm_free_us;
+ INIT_HLIST_NODE(&sm->page_list);
+ sm->data = task;
+}
+
+void free_sm_us(struct slot_manager *sm)
+{
+ /* FIXME: free */
+}
+
+struct pf_data {
+ unsigned long addr;
+};
+
+static int entry_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs);
+static int ret_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs);
+
+static struct kretprobe pf_kretprobe = {
+ .entry_handler = entry_handler_pf,
+ .handler = ret_handler_pf,
+ .data_size = sizeof(struct pf_data)
+};
+
+static void copy_process_ret_pre_code(struct task_struct *p);
+
+static int ret_handler_cp(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+ struct task_struct* task = (struct task_struct *)regs_return_value(regs);
+
+ copy_process_ret_pre_code(task);
+
+ return 0;
+}
+
+static struct kretprobe cp_kretprobe = {
+ .handler = ret_handler_cp,
+};
+
+static void jmm_release(struct task_struct *tsk, struct mm_struct *mm);
+
+static struct jprobe mr_jprobe = {
+ .entry = jmm_release
+};
+
+static int jdo_munmap(struct mm_struct *mm, unsigned long start, size_t len);
+
+static struct jprobe unmap_jprobe = {
+ .entry = jdo_munmap
+};
+
static struct sspt_procs *get_proc_probes_by_task(struct task_struct *task)
{
struct sspt_procs *procs, *tmp;
struct sspt_procs *procs = get_proc_probes_by_task(task);
if (procs == NULL) {
procs = sspt_procs_copy(us_proc_info.pp, task);
+ procs->sm = create_sm_us(task);
add_proc_probes(task, procs);
}
return procs;
}
-#ifdef SLP_APP
-static int is_slp_app_with_dentry(struct vm_area_struct *vma,
- struct dentry *dentry)
-{
- struct vm_area_struct *slp_app_vma = NULL;
-
- if (vma->vm_file->f_dentry == launchpad_daemon_dentry) {
- slp_app_vma = vma;
- while (slp_app_vma) {
- if (slp_app_vma->vm_file) {
- if (slp_app_vma->vm_file->f_dentry == dentry &&
- slp_app_vma->vm_pgoff == 0) {
- return 1;
- }
- }
- slp_app_vma = slp_app_vma->vm_next;
- }
- }
-
- return 0;
-}
-#endif /* SLP_APP */
-
-#ifdef ANDROID_APP
-static int is_android_app_with_dentry(struct vm_area_struct *vma,
- struct dentry *dentry)
-{
- struct vm_area_struct *android_app_vma = NULL;
-
- if (vma->vm_file->f_dentry == app_process_dentry) {
- android_app_vma = vma;
- while (android_app_vma) {
- if (android_app_vma->vm_file) {
- if (android_app_vma->vm_file->f_dentry == dentry) {
- android_app_vma_start = android_app_vma->vm_start;
- android_app_vma_end = android_app_vma->vm_end;
- return 1;
- }
- }
- android_app_vma = android_app_vma->vm_next;
- }
- }
-
- return 0;
-}
-#endif /* ANDROID_APP */
-
struct dentry *dentry_by_path(const char *path)
{
struct dentry *dentry;
static int check_vma(struct vm_area_struct *vma)
{
-#ifndef __ANDROID
return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || (vma->vm_flags & VM_ACCOUNT) ||
!(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
!(vma->vm_flags & (VM_READ | VM_MAYREAD)));
-#else // __ANDROID
- return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC));
-#endif // __ANDROID
}
static int find_task_by_path (const char *path, struct task_struct **p_task, struct list_head *tids)
}
//break;
}
-#ifdef SLP_APP
- if (!*p_task) {
- if (is_slp_app_with_dentry(vma, dentry)) {
- *p_task = task;
- get_task_struct(task);
- }
- }
-#endif /* SLP_APP */
-#ifdef ANDROID_APP
- if (!*p_task) {
- if (is_android_app_with_dentry(vma, dentry)) {
- *p_task = task;
- get_task_struct(task);
- }
- }
-#endif /* ANDROID_APP */
}
vma = vma->vm_next;
}
int install_otg_ip(unsigned long addr,
kprobe_pre_entry_handler_t pre_handler,
unsigned long jp_handler,
- kretprobe_handler_t rp_handler)
+ uretprobe_handler_t rp_handler)
{
int ret = 0;
struct task_struct *task = current->group_leader;
}
EXPORT_SYMBOL_GPL(install_otg_ip);
-static int uninstall_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
+int init_helper(void)
{
- kernel_probe_t *probe = NULL;
- int iRet = 0;
- if (probes_flags & kflag) {
- probe = find_probe(addr);
- if (probe) {
- iRet = remove_probe_from_list (addr);
- if (iRet)
- EPRINTF ("remove_probe_from_list(0x%lx) result=%d!", addr, iRet);
- if (pprobe)
- *pprobe = NULL;
- }
- probes_flags &= ~kflag;
- }
- if (us_proc_probes & uflag) {
- if (!(probes_flags & uflag)) {
- if (probe) {
- iRet = unregister_kernel_probe(probe);
- if (iRet) {
- EPRINTF ("unregister_kernel_probe(0x%lx) result=%d!",
- addr, iRet);
- return iRet;
- }
- }
- }
- us_proc_probes &= ~uflag;
+ unsigned long addr;
+ addr = swap_ksyms("do_page_fault");
+ if (addr == 0) {
+ EPRINTF("Cannot find address for page fault function!");
+ return -EINVAL;
}
- return iRet;
+ pf_kretprobe.kp.addr = (kprobe_opcode_t *)addr;
+
+ addr = swap_ksyms("copy_process");
+ if (addr == 0) {
+ EPRINTF("Cannot find address for copy_process function!");
+ return -EINVAL;
+ }
+ cp_kretprobe.kp.addr = (kprobe_opcode_t *)addr;
+
+ addr = swap_ksyms("mm_release");
+ if (addr == 0) {
+ EPRINTF("Cannot find address for mm_release function!");
+ return -EINVAL;
+ }
+ mr_jprobe.kp.addr = (kprobe_opcode_t *)addr;
+
+ addr = swap_ksyms("do_munmap");
+ if (addr == 0) {
+ EPRINTF("Cannot find address for do_munmap function!");
+ return -EINVAL;
+ }
+ unmap_jprobe.kp.addr = (kprobe_opcode_t *)addr;
+
+ return 0;
+}
+
+void uninit_helper(void)
+{
+}
+
+static int register_helper_ks_probes(void)
+{
+ int ret = 0;
+
+ /* install jprobe on 'do_munmap' to detect when for remove user space probes */
+ ret = dbi_register_jprobe(&unmap_jprobe);
+ if (ret) {
+ EPRINTF("dbi_register_jprobe(do_munmap) result=%d!", ret);
+ return ret;
+ }
+
+ /* install jprobe on 'mm_release' to detect when for remove user space probes */
+ ret = dbi_register_jprobe(&mr_jprobe);
+ if (ret != 0) {
+ EPRINTF("dbi_register_jprobe(mm_release) result=%d!", ret);
+ goto unregister_unmap;
+ }
+
+
+ /* install kretprobe on 'copy_process' */
+ ret = dbi_register_kretprobe(&cp_kretprobe);
+ if (ret) {
+ EPRINTF("dbi_register_kretprobe(copy_process) result=%d!", ret);
+ goto unregister_mr;
+ }
+
+ /* install kretprobe on 'do_page_fault' to detect when they will be loaded */
+ ret = dbi_register_kretprobe(&pf_kretprobe);
+ if (ret) {
+ EPRINTF("dbi_register_kretprobe(do_page_fault) result=%d!", ret);
+ goto unregister_cp;
+ }
+
+ return ret;
+
+unregister_cp:
+ dbi_unregister_kretprobe(&cp_kretprobe);
+
+unregister_mr:
+ dbi_unregister_jprobe(&mr_jprobe);
+
+unregister_unmap:
+ dbi_unregister_jprobe(&unmap_jprobe);
+
+ return ret;
+}
+
+static void unregister_helper_ks_probes(void)
+{
+ /* uninstall kretprobe with 'do_page_fault' */
+ dbi_unregister_kretprobe(&pf_kretprobe);
+
+ /* uninstall kretprobe with 'copy_process' */
+ dbi_unregister_kretprobe(&cp_kretprobe);
+
+ /* uninstall jprobe with 'mm_release' */
+ dbi_unregister_jprobe(&mr_jprobe);
+
+ /* uninstall jprobe with 'do_munmap' */
+ dbi_unregister_jprobe(&unmap_jprobe);
}
static int uninstall_us_proc_probes(struct task_struct *task, struct sspt_procs *procs, enum US_FLAGS flag);
return 0;
}
- iRet = uninstall_kernel_probe (pf_addr, US_PROC_PF_INSTLD,
- 0, &pf_probe);
- if (iRet)
- EPRINTF ("uninstall_kernel_probe(do_page_fault) result=%d!", iRet);
-
- iRet = uninstall_kernel_probe (cp_addr, US_PROC_CP_INSTLD,
- 0, &cp_probe);
- if (iRet)
- EPRINTF ("uninstall_kernel_probe(copy_process) result=%d!", iRet);
-
- iRet = uninstall_kernel_probe (mr_addr, US_PROC_MR_INSTLD,
- 0, &mr_probe);
- if (iRet)
- EPRINTF ("uninstall_kernel_probe(mm_release) result=%d!", iRet);
-
- iRet = uninstall_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD,
- 0, &exit_probe);
- if (iRet)
- EPRINTF ("uninstall_kernel_probe(do_exit) result=%d!", iRet);
-
- iRet = uninstall_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD,
- 0, &unmap_probe);
if (iRet)
EPRINTF ("uninstall_kernel_probe(do_munmap) result=%d!", iRet);
}
}
- return iRet;
-}
-static int install_kernel_probe (unsigned long addr, int uflag, int kflag, kernel_probe_t ** pprobe)
-{
- kernel_probe_t *probe = NULL;
- int iRet = 0;
-
- DPRINTF("us_proc_probes = 0x%x, uflag = 0x%x, "
- "probes_flags = 0x%x, kflag = 0x%x",
- us_proc_probes, uflag, probes_flags, kflag);
-
- if (!(probes_flags & kflag)) {
- iRet = add_probe_to_list (addr, &probe);
- if (iRet) {
- EPRINTF ("add_probe_to_list(0x%lx) result=%d!", addr, iRet);
- return iRet;
- }
- probes_flags |= kflag;
- }
- if (!(us_proc_probes & uflag)) {
- if (!(probes_flags & uflag)) {
- iRet = register_kernel_probe (probe);
- if (iRet) {
- EPRINTF ("register_kernel_probe(0x%lx) result=%d!", addr, iRet);
- return iRet;
- }
- }
- us_proc_probes |= uflag;
- }
-
- if (probe)
- *pprobe = probe;
+ unregister_helper_ks_probes();
- return 0;
+ return iRet;
}
static void install_proc_probes(struct task_struct *task, struct sspt_procs *procs, int atomic);
DPRINTF("User space instr");
-#ifdef SLP_APP
- launchpad_daemon_dentry = dentry_by_path("/usr/bin/launchpad_preloading_preinitializing_daemon");
- if (launchpad_daemon_dentry == NULL) {
- return -EINVAL;
- }
-
-#endif /* SLP_APP */
-
-#ifdef ANDROID_APP
- app_process_dentry = dentry_by_path("/system/bin/app_process");
- if (app_process_dentry == NULL) {
- return -EINVAL;
+ ret = register_helper_ks_probes();
+ if (ret) {
+ return ret;
}
- android_app_vma_start = 0;
- android_app_vma_end = 0;
-#endif /* ANDROID_APP */
-
for (i = 0; i < us_proc_info.libs_count; i++) {
us_proc_info.p_libs[i].loaded = 0;
}
{
DPRINTF("task found. installing probes");
us_proc_info.tgid = task->pid;
+ us_proc_info.pp->sm = create_sm_us(task);
install_proc_probes(task, us_proc_info.pp, 0);
put_task_struct (task);
}
}
- // enable 'do_page_fault' probe to detect when they will be loaded
- ret = install_kernel_probe (pf_addr, US_PROC_PF_INSTLD, 0, &pf_probe);
- if (ret != 0)
- {
- EPRINTF ("install_kernel_probe(do_page_fault) result=%d!", ret);
- return ret;
- }
- // enable 'do_exit' probe to detect for remove task_struct
- ret = install_kernel_probe (exit_addr, US_PROC_EXIT_INSTLD, 0, &exit_probe);
- if (ret != 0)
- {
- EPRINTF ("install_kernel_probe(do_exit) result=%d!", ret);
- return ret;
- }
- /* enable 'copy_process' */
- ret = install_kernel_probe (cp_addr, US_PROC_CP_INSTLD, 0, &cp_probe);
- if (ret != 0)
- {
- EPRINTF ("instpall_kernel_probe(copy_process) result=%d!", ret);
- return ret;
- }
-
- // enable 'mm_release' probe to detect when for remove user space probes
- ret = install_kernel_probe (mr_addr, US_PROC_MR_INSTLD, 0, &mr_probe);
- if (ret != 0)
- {
- EPRINTF ("install_kernel_probe(mm_release) result=%d!", ret);
- return ret;
- }
-
- // enable 'do_munmap' probe to detect when for remove user space probes
- ret = install_kernel_probe (unmap_addr, US_PROC_UNMAP_INSTLD, 0, &unmap_probe);
- if (ret != 0)
- {
- EPRINTF ("install_kernel_probe(do_munmap) result=%d!", ret);
- return ret;
- }
return 0;
}
-#include "../../tools/gpmu/probes/entry_data.h"
-
-void do_page_fault_j_pre_code(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
-{
- struct task_struct *task = current->group_leader;
-
- if (task->flags & PF_KTHREAD) {
- DPRINTF("ignored kernel thread %d\n", task->pid);
- return;
- }
-
- if (is_us_instrumentation()) {
- swap_put_entry_data((void *)addr, &sa_dpf);
- }
-}
-EXPORT_SYMBOL_GPL(do_page_fault_j_pre_code);
-
-
unsigned long imi_sum_time = 0;
unsigned long imi_sum_hit = 0;
if (vma->vm_file->f_dentry == dentry) {
return task->tgid;
}
-#ifdef SLP_APP
- if (is_slp_app_with_dentry(vma, dentry)) {
- return task->tgid;
- }
-#endif /* SLP_APP */
-#ifdef ANDROID_APP
- if (is_android_app_with_dentry(vma, dentry)) {
- return task->tgid;
- }
-#endif /* ANDROID_APP */
}
}
return 0;
}
-void do_page_fault_ret_pre_code (void)
+static int entry_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+ struct pf_data *data = (struct pf_data *)ri->data;
+
+ /* for ARM arch*/
+ data->addr = regs->ARM_r0;
+ return 0;
+}
+
+/* Detects when IPs are really loaded into phy mem and installs probes. */
+static int ret_handler_pf(struct kretprobe_instance *ri, struct pt_regs *regs)
{
struct task_struct *task = current->group_leader;
struct mm_struct *mm = task->mm;
* Because process threads have same address space
* we instrument only group_leader of all this threads
*/
+ struct pf_data *data;
unsigned long addr = 0;
int valid_addr;
#define USEC_IN_SEC_NUM 1000000
if (task->flags & PF_KTHREAD) {
- DPRINTF("ignored kernel thread %d\n", task->pid);
- return;
+ goto out;
}
if (!is_us_instrumentation()) {
- return;
+ goto out;
}
- addr = (unsigned long)swap_get_entry_data(&sa_dpf);
-
- if (addr == 0) {
- printk("WARNING: do_page_fault_ret_pre_code addr = 0\n");
- return;
- }
-
-
-
+ data = (struct pf_data *)ri->data;
+ addr = data->addr;
valid_addr = mm && page_present(mm, addr);
if (!valid_addr) {
- return;
+ goto out;
}
if (is_libonly()) {
if (tgid) {
us_proc_info.tgid = gl_nNotifyTgid = tgid;
+ us_proc_info.pp->sm = create_sm_us(task);
/* install probes in already mapped memory */
install_proc_probes(task, us_proc_info.pp, 1);
}
imi_sum_time += ((imi_tv2.tv_sec - imi_tv1.tv_sec) * USEC_IN_SEC_NUM +
(imi_tv2.tv_usec - imi_tv1.tv_usec));
}
-}
-
-EXPORT_SYMBOL_GPL(do_page_fault_ret_pre_code);
-
-void do_exit_probe_pre_code (void)
-{
- // TODO: remove task
+out:
+ return 0;
}
-EXPORT_SYMBOL_GPL(do_exit_probe_pre_code);
void print_vma(struct mm_struct *mm)
{
file = sspt_procs_find_file(procs, dentry);
if (file) {
if (vma->vm_start == start || vma->vm_end == end) {
- unregister_us_file_probes(task, file, US_NOT_RP2);
+ unregister_us_file_probes(task, file, US_UNREGS_PROBE);
file->loaded = 0;
} else {
unsigned long page_addr;
for (page_addr = vma->vm_start; page_addr < vma->vm_end; page_addr += PAGE_SIZE) {
page = sspt_find_page_mapped(file, page_addr);
if (page) {
- unregister_us_page_probe(task, page, US_NOT_RP2);
+ unregister_us_page_probe(task, page, US_UNREGS_PROBE);
}
}
return 0;
}
-void do_munmap_probe_pre_code(struct mm_struct *mm, unsigned long start, size_t len)
+/* Detects when target removes IPs. */
+static int jdo_munmap(struct mm_struct *mm, unsigned long start, size_t len)
{
struct sspt_procs *procs = NULL;
struct task_struct *task = current;
//if user-space instrumentation is not set
if (!is_us_instrumentation()) {
- return;
+ goto out;
}
if (is_libonly()) {
printk("ERROR do_munmap: start=%lx, len=%x\n", start, len);
}
}
+
+out:
+ dbi_jprobe_return();
+ return 0;
}
-EXPORT_SYMBOL_GPL(do_munmap_probe_pre_code);
-void mm_release_probe_pre_code(void)
+/* Detects when target process removes IPs. */
+static void jmm_release(struct task_struct *task, struct mm_struct *mm)
{
- struct task_struct *task = current;
struct sspt_procs *procs = NULL;
if (!is_us_instrumentation() || task->tgid != task->pid) {
- return;
+ goto out;
}
if (is_libonly()) {
}
if (procs) {
- int ret = uninstall_us_proc_probes(task, procs, US_NOT_RP2);
+ int ret = uninstall_us_proc_probes(task, procs, US_UNREGS_PROBE);
if (ret != 0) {
EPRINTF ("failed to uninstall IPs (%d)!", ret);
}
dbi_unregister_all_uprobes(task, 1);
}
-}
-EXPORT_SYMBOL_GPL(mm_release_probe_pre_code);
+out:
+ dbi_jprobe_return();
+}
static void recover_child(struct task_struct *child_task, struct sspt_procs *procs)
{
}
}
-void copy_process_ret_pre_code(struct task_struct *p)
+/* Delete uprobs in children at fork */
+static void copy_process_ret_pre_code(struct task_struct *p)
{
if(!p || IS_ERR(p))
return;
void ujprobe_event_handler (unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned long arg6)
{
struct us_ip *ip = __get_cpu_var(gpCurIp);
- unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
-
-#ifdef __ANDROID
- struct pt_regs *regs = __get_cpu_var(gpUserRegs);
- if (is_java_inst_enabled() && handle_java_event(regs)) {
- return;
- }
-#endif /* __ANDROID */
-
+ unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
#if defined(CONFIG_ARM)
if (ip->offset & 0x01)
static void send_plt(struct us_ip *ip)
{
- unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
+ unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
struct vm_area_struct *vma = find_vma(current->mm, addr);
if (vma && check_vma(vma)) {
}
}
-int uretprobe_event_handler(struct kretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip)
+int uretprobe_event_handler(struct uretprobe_instance *probe, struct pt_regs *regs, struct us_ip *ip)
{
int retval = regs_return_value(regs);
- unsigned long addr = (unsigned long)ip->jprobe.kp.addr;
+ unsigned long addr = (unsigned long)ip->jprobe.up.kp.addr;
if (ip->got_addr && ip->flag_got == 0) {
send_plt(ip);
int register_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
{
int ret = 0;
- ip->jprobe.kp.tgid = task->tgid;
if (ip->jprobe.entry == NULL) {
- ip->jprobe.entry = (kprobe_opcode_t *)ujprobe_event_handler;
+ ip->jprobe.entry = (void *)ujprobe_event_handler;
DPRINTF("Set default event handler for %x\n", ip->offset);
}
if (ip->jprobe.pre_entry == NULL) {
- ip->jprobe.pre_entry = (kprobe_pre_entry_handler_t)ujprobe_event_pre_handler;
+ ip->jprobe.pre_entry = (uprobe_pre_entry_handler_t)ujprobe_event_pre_handler;
DPRINTF("Set default pre handler for %x\n", ip->offset);
}
ip->jprobe.priv_arg = ip;
- ret = dbi_register_ujprobe(task, &ip->jprobe, atomic);
+ ip->jprobe.up.task = task;
+ ip->jprobe.up.sm = ip->page->file->procs->sm;
+ ret = dbi_register_ujprobe(&ip->jprobe, atomic);
if (ret) {
if (ret == -ENOEXEC) {
pack_event_info(ERR_MSG_ID, RECORD_ENTRY, "dp",
0x1,
- ip->jprobe.kp.addr);
+ ip->jprobe.up.kp.addr);
}
DPRINTF ("dbi_register_ujprobe() failure %d", ret);
return ret;
if (ip->flag_retprobe) {
// Mr_Nobody: comment for valencia
- ip->retprobe.kp.tgid = task->tgid;
if (ip->retprobe.handler == NULL) {
- ip->retprobe.handler = (kretprobe_handler_t)uretprobe_event_handler;
+ ip->retprobe.handler = (uretprobe_handler_t)uretprobe_event_handler;
DPRINTF("Set default ret event handler for %x\n", ip->offset);
}
ip->retprobe.priv_arg = ip;
- ret = dbi_register_uretprobe(task, &ip->retprobe, atomic);
+ ip->retprobe.up.task = task;
+ ip->retprobe.up.sm = ip->page->file->procs->sm;
+ ret = dbi_register_uretprobe(&ip->retprobe, atomic);
if (ret) {
EPRINTF ("dbi_register_uretprobe() failure %d", ret);
return ret;
return 0;
}
-int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic, int not_rp2)
+int unregister_usprobe(struct task_struct *task, struct us_ip *ip, int atomic)
{
- dbi_unregister_ujprobe(task, &ip->jprobe, atomic);
+ dbi_unregister_ujprobe(&ip->jprobe, atomic);
if (ip->flag_retprobe) {
- dbi_unregister_uretprobe(task, &ip->retprobe, atomic, not_rp2);
+ dbi_unregister_uretprobe(&ip->retprobe, atomic);
}
return 0;
}
-
-unsigned long get_stack_size(struct task_struct *task,
- struct pt_regs *regs)
-{
-#ifdef CONFIG_ADD_THREAD_STACK_INFO
- return (task->stack_start - dbi_get_stack_ptr(regs));
-#else
- struct vm_area_struct *vma = NULL;
- struct mm_struct *mm = NULL;
- unsigned long result = 0;
- int atomic = in_atomic();
-
- mm = (atomic ? task->active_mm: get_task_mm(task));
-
- if (mm) {
- if (!atomic)
- down_read(&mm->mmap_sem);
-
- vma = find_vma(mm, dbi_get_stack_ptr(regs));
-
- if (vma)
- result = vma->vm_end - dbi_get_stack_ptr(regs);
- else
- result = 0;
-
- if (!atomic) {
- up_read(&mm->mmap_sem);
- mmput(mm);
- }
- }
-
- return result;
-#endif
-}
-EXPORT_SYMBOL_GPL(get_stack_size);
-
-unsigned long get_stack(struct task_struct *task, struct pt_regs *regs,
- char *buf, unsigned long sz)
-{
- unsigned long stack_sz = get_stack_size(task, regs);
- unsigned long real_sz = (stack_sz > sz ? sz: stack_sz);
- int res = read_proc_vm_atomic(task, dbi_get_stack_ptr(regs), buf, real_sz);
- return res;
-}
-EXPORT_SYMBOL_GPL(get_stack);
-
-int dump_to_trace(probe_id_t probe_id, void *addr, const char *buf,
- unsigned long sz)
-{
- unsigned long rest_sz = sz;
- const char *data = buf;
-
- while (rest_sz >= EVENT_MAX_SIZE) {
- pack_event_info(probe_id, RECORD_ENTRY, "pa",
- addr, EVENT_MAX_SIZE, data);
- rest_sz -= EVENT_MAX_SIZE;
- data += EVENT_MAX_SIZE;
- }
-
- if (rest_sz > 0)
- pack_event_info(probe_id, RECORD_ENTRY, "pa", addr, rest_sz, data);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(dump_to_trace);
-
-int dump_backtrace(probe_id_t probe_id, struct task_struct *task,
- void *addr, struct pt_regs *regs, unsigned long sz)
-{
- unsigned long real_sz = 0;
- char *buf = NULL;
-
- buf = (char *)kmalloc(sz, GFP_ATOMIC);
-
- if (buf != NULL) {
- real_sz = get_stack(task, regs, buf, sz);
- if (real_sz > 0)
- dump_to_trace(probe_id, addr, buf, real_sz);
- kfree(buf);
- return 0;
- } else {
- return -1;
- }
-}
-EXPORT_SYMBOL_GPL(dump_backtrace);
-
-struct kretprobe_instance *find_ri(struct task_struct *task, struct us_ip *ip)
-{
- struct hlist_node *item, *tmp_node;
- struct kretprobe_instance *ri;
-
- if (ip == NULL)
- return NULL;
-
- hlist_for_each_safe (item, tmp_node, &ip->retprobe.used_instances) {
- ri = hlist_entry (item, struct kretprobe_instance, uflist);
-
- if (ri->task && ri->task->pid == task->pid &&
- ri->task->tgid == task->tgid)
- return ri;
- }
-
- return NULL;
-}
-EXPORT_SYMBOL_GPL(find_ri);
-
-unsigned long get_ret_addr(struct task_struct *task, struct us_ip *ip)
-{
- struct kretprobe_instance *ri = find_ri(task, ip);;
- if (ri)
- return (unsigned long)ri->ret_addr;
- else
- return dbi_get_ret_addr(task_pt_regs(task));
-}
-EXPORT_SYMBOL_GPL(get_ret_addr);
-
-unsigned long get_entry_sp(struct task_struct *task, struct us_ip *ip)
-{
- struct kretprobe_instance *ri = find_ri(task, ip);
- if (ri)
- return (unsigned long)ri->sp;
- else
- return dbi_get_stack_ptr(task_pt_regs(task));
-}
-EXPORT_SYMBOL_GPL(get_entry_sp);