[FEATURE] start ui viewer implementation 58/55258/1
authorAnastasia Lyupa <a.lyupa@samsung.com>
Mon, 27 Jul 2015 12:52:51 +0000 (15:52 +0300)
committerAlexander Aksenov <a.aksenov@samsung.com>
Tue, 22 Dec 2015 14:25:03 +0000 (17:25 +0300)
preload ui viewer lib during main func execution

Change-Id: Icb4d7432c41518a6f3c35d54aa30d9b9d450a44d
Signed-off-by: Anastasia Lyupa <a.lyupa@samsung.com>
preload/preload_debugfs.c
preload/preload_module.c
preload/preload_module.h
preload/preload_pd.c
preload/preload_pd.h
preload/preload_probe.c
preload/preload_storage.c
preload/preload_storage.h
us_manager/probes/probe_info_new.c

index ba3fd66..7e2955b 100644 (file)
@@ -24,6 +24,8 @@ static const char PRELOAD_BINARIES_ADD[] = "bins_add";
 static const char PRELOAD_BINARIES_REMOVE[] = "bins_remove";
 static const char PRELOAD_CALLER[] = "caller";
 static const char PRELOAD_HANDLERS_PATH[] = "handlers_path";
+static const char PRELOAD_UI_VIEWER_PATH[] = "ui_viewer_path";
+static const char PRELOAD_UI_VIEWER_APP_INFO[] = "ui_viewer_app_info";
 static const char PRELOAD_LINKER_DATA[] = "linker";
 static const char PRELOAD_LINKER_PATH[] = "linker_path";
 static const char PRELOAD_LINKER_R_DEBUG_OFFSET[] = "r_debug_offset";
@@ -363,6 +365,126 @@ static const struct file_operations handlers_path_file_ops = {
 };
 
 
+/* ===========================================================================
+ * =                           UI VIEWER PATH                                =
+ * ===========================================================================
+ */
+
+
+static ssize_t ui_viewer_path_write(struct file *file, const char __user *buf,
+                                  size_t len, loff_t *ppos)
+{
+       ssize_t ret;
+       char *path;
+
+       path = kmalloc(len, GFP_KERNEL);
+       if (path == NULL) {
+               ret = -ENOMEM;
+               goto ui_viewer_path_write_out;
+       }
+
+       if (copy_from_user(path, buf, len)) {
+               ret = -EINVAL;
+               goto ui_viewer_path_write_out;
+       }
+
+       path[len - 1] = '\0';
+
+       if (preload_storage_set_ui_viewer_info(path) != 0) {
+               printk(PRELOAD_PREFIX "Cannot set ui viewer path %s\n", path);
+               ret = -EINVAL;
+               goto ui_viewer_path_write_out;
+       }
+
+       ret = len;
+
+       printk(PRELOAD_PREFIX "Set ui viewer path %s\n", path);
+
+ui_viewer_path_write_out:
+       kfree(path);
+
+       return ret;
+}
+
+static const struct file_operations ui_viewer_path_file_ops = {
+       .owner = THIS_MODULE,
+       .write = ui_viewer_path_write,
+};
+
+
+/*
+ * format:
+ *     main:app_path
+ *
+ * sample:
+ *     0x00000d60:/bin/app_sample
+ */
+static int ui_viewer_add_app_info(const char *buf, size_t len)
+{
+       int n, ret;
+       char *app_path;
+       unsigned long main_addr;
+       const char fmt[] = "%%lx:/%%%ds";
+       char fmt_buf[64];
+
+       n = snprintf(fmt_buf, sizeof(fmt_buf), fmt, PATH_MAX - 2);
+       if (n <= 0)
+               return -EINVAL;
+
+       app_path = kmalloc(PATH_MAX, GFP_KERNEL);
+       if (app_path == NULL)
+               return -ENOMEM;
+
+       n = sscanf(buf, fmt_buf, &main_addr, app_path + 1);
+       if (n != 2) {
+               ret = -EINVAL;
+               goto free_app_path;
+       }
+       app_path[0] = '/';
+
+       printk(PRELOAD_PREFIX "Set ui viewer app path %s, main offset 0x%lx\n", app_path, main_addr);
+
+       ret = preload_ui_viewer_data_set(app_path, main_addr);
+
+free_app_path:
+       kfree(app_path);
+       return ret;
+}
+
+static ssize_t write_ui_viewer_app_info(struct file *file,
+                                       const char __user *user_buf,
+                                       size_t len, loff_t *ppos)
+{
+       ssize_t ret;
+       char *buf;
+
+       buf = kmalloc(len, GFP_KERNEL);
+       if (buf == NULL) {
+               ret = -ENOMEM;
+               goto free_buf;
+       }
+
+       if (copy_from_user(buf, user_buf, len)) {
+               ret = -EINVAL;
+               goto free_buf;
+       }
+
+       buf[len - 1] = '\0';
+
+       if (ui_viewer_add_app_info(buf, len))
+               ret = -EINVAL;
+
+free_buf:
+       kfree(buf);
+
+       return ret;
+}
+
+static const struct file_operations ui_viewer_app_info_file_ops = {
+       .owner = THIS_MODULE,
+       .write =        write_ui_viewer_app_info,
+};
+
 
 
 unsigned long preload_debugfs_r_debug_offset(void)
@@ -374,7 +496,8 @@ int preload_debugfs_init(void)
 {
        struct dentry *swap_dentry, *root, *loader, *open_p, *lib_path,
                  *bin_path, *bin_list, *bin_add, *bin_remove,
-                 *linker_dir, *linker_path, *linker_offset, *handlers_path;
+                 *linker_dir, *linker_path, *linker_offset, *handlers_path,
+                 *ui_viewer_path, *ui_viewer_app_info;
        int ret;
 
        ret = -ENODEV;
@@ -471,6 +594,22 @@ int preload_debugfs_init(void)
                goto remove;
        }
 
+       ui_viewer_path = debugfs_create_file(PRELOAD_UI_VIEWER_PATH,
+                                           PRELOAD_DEFAULT_PERMS, root, NULL,
+                                           &ui_viewer_path_file_ops);
+       if (IS_ERR_OR_NULL(ui_viewer_path)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
+       ui_viewer_app_info = debugfs_create_file(PRELOAD_UI_VIEWER_APP_INFO,
+                                           PRELOAD_DEFAULT_PERMS, root, NULL,
+                                           &ui_viewer_app_info_file_ops);
+       if (IS_ERR_OR_NULL(ui_viewer_app_info)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
        return 0;
 
 remove:
index c105fd0..261f64d 100644 (file)
 #include <kprobe/swap_kprobes.h>
 #include <kprobe/swap_kprobes_deps.h>
 #include <us_manager/us_manager_common.h>
+#include <us_manager/pf/pf_group.h>
 #include <us_manager/sspt/sspt_page.h>
 #include <us_manager/sspt/sspt_file.h>
 #include <us_manager/sspt/sspt_proc.h>
 #include <us_manager/sspt/ip.h>
 #include <us_manager/callbacks.h>
+#include <us_manager/probes/probe_info_new.h>
 #include <writer/kernel_operations.h>
 #include <master/swap_initializer.h>
 #include <writer/swap_msg.h>
-#include <task_data/task_data.h>
 #include "preload.h"
 #include "preload_probe.h"
 #include "preload_debugfs.h"
@@ -516,6 +517,7 @@ static inline void __write_data_to_msg(char *msg, size_t len,
 enum mmap_type_t {
        MMAP_LOADER,
        MMAP_HANDLERS,
+       MMAP_UI_VIEWER,
        MMAP_SKIP
 };
 
@@ -535,7 +537,7 @@ static int mmap_entry_handler(struct kretprobe_instance *ri,
        unsigned long prot = swap_get_karg(regs, 3);
        struct mmap_priv *priv = (struct mmap_priv *)ri->data;
        struct dentry *dentry, *loader_dentry;
-       struct bin_info *hi;
+       struct bin_info *hi, *vi;
 
        priv->type = MMAP_SKIP;
        if (!check_prot(prot))
@@ -554,12 +556,23 @@ static int mmap_entry_handler(struct kretprobe_instance *ri,
                return 0;
        }
 
+       vi = preload_storage_get_ui_viewer_info();
+       if (vi == NULL) {
+               printk(PRELOAD_PREFIX "Cannot get ui viewer info [%u %u %s]\n",
+                      current->tgid, current->pid, current->comm);
+               goto put_hi;
+       }
+
        loader_dentry = preload_debugfs_get_loader_dentry();
        if (dentry == loader_dentry)
                priv->type = MMAP_LOADER;
        else if (hi->dentry != NULL && dentry == hi->dentry)
                priv->type = MMAP_HANDLERS;
+       else if (vi->dentry != NULL && dentry == vi->dentry)
+               priv->type = MMAP_UI_VIEWER;
 
+       preload_storage_put_handlers_info(vi);
+put_hi:
        preload_storage_put_handlers_info(hi);
 
        return 0;
@@ -599,6 +612,9 @@ static int mmap_ret_handler(struct kretprobe_instance *ri,
        case MMAP_HANDLERS:
                preload_pd_set_handlers_base(pd, vaddr);
                break;
+       case MMAP_UI_VIEWER:
+               preload_pd_set_ui_viewer_base(proc->private_data, vaddr);
+               break;
        case MMAP_SKIP:
        default:
                break;
@@ -658,7 +674,7 @@ static int preload_us_entry(struct uretprobe_instance *ri, struct pt_regs *regs)
                if (vaddr) {
                        /* save original regs state */
                        __save_uregs(ri, regs);
-                       print_regs("ORIG", regs, ri);
+                       print_regs("PROBE ORIG", regs, ri);
 
                        path = preload_pd_get_path(pd);
 
@@ -745,16 +761,14 @@ static int preload_us_ret(struct uretprobe_instance *ri, struct pt_regs *regs)
 
                        /* restore original regs state */
                        __restore_uregs(ri, regs);
-                       print_regs("REST", regs, ri);
+                       print_regs("PROBE REST", regs, ri);
                        /* check if preloading done */
 
                        if (preload_pd_get_handle(pd)) {
                                preload_pd_set_state(pd, LOADED);
-                               preload_pd_put_path(pd);
                        } else {
                                preload_pd_dec_attempts(pd);
                                preload_pd_set_state(pd, FAILED);
-                               preload_pd_put_path(pd);
                        }
                }
                break;
@@ -779,7 +793,6 @@ static int preload_us_ret(struct uretprobe_instance *ri, struct pt_regs *regs)
        case FAILED:
                if (preload_pd_get_attempts(pd)) {
                        preload_pd_set_state(pd, NOT_LOADED);
-                       preload_pd_put_path(pd);
                }
                break;
        case ERROR:
@@ -962,6 +975,171 @@ void preload_unset(void)
 
 }
 
+
+/* ============================================================================
+ * =                               ui_viewer                                  =
+ * ============================================================================
+ */
+
+/* main handler for ui viewer */
+static int preload_ui_viewer_main_eh(struct uretprobe_instance *ri,
+                              struct pt_regs *regs);
+static int preload_ui_viewer_main_rh(struct uretprobe_instance *ri,
+                              struct pt_regs *regs);
+static struct probe_info_new pin_main = MAKE_URPROBE(preload_ui_viewer_main_eh,
+                                                    preload_ui_viewer_main_rh,
+                                                    0);
+
+struct ui_viewer_data {
+       struct dentry *app_dentry;
+       struct probe_new p_main;
+       struct pf_group *pfg;
+};
+
+static struct ui_viewer_data __ui_data;
+
+static int preload_ui_viewer_data_inst(void)
+{
+       int ret;
+       struct pf_group *pfg;
+
+       pfg = get_pf_group_by_dentry(__ui_data.app_dentry,
+                                    (void *)__ui_data.app_dentry);
+       if (pfg == NULL)
+               return -ENOMEM;
+
+       ret = pin_register(&__ui_data.p_main, pfg, __ui_data.app_dentry);
+       if (ret)
+               goto put_g;
+
+       __ui_data.pfg = pfg;
+
+       return 0;
+put_g:
+       put_pf_group(pfg);
+       return ret;
+}
+
+/*
+static void preload_ui_viewer_data_uninst(void)
+{
+       struct pf_group *pfg = __ui_data.pfg;
+
+       pin_unregister(&__ui_data.p_main, pfg, __ui_data.app_dentry);
+
+       put_pf_group(pfg);
+
+       __ui_data.pfg = NULL;
+}
+*/
+
+static int preload_ui_viewer_init(struct us_ip *ip)
+{
+       return 0;
+}
+
+static void preload_ui_viewer_exit(struct us_ip *ip)
+{
+       return;
+}
+
+int preload_ui_viewer_data_set(const char *app_path, unsigned long main_addr)
+{
+       struct dentry *dentry;
+
+       dentry = dentry_by_path(app_path);
+       if (dentry == NULL)
+               return -ENOENT;
+
+       __ui_data.app_dentry = dentry;
+       __ui_data.p_main.info = &pin_main;
+       __ui_data.p_main.offset = main_addr;
+       __ui_data.pfg = NULL;
+
+       preload_ui_viewer_data_inst();
+
+       return 0;
+}
+
+/* ============================================================================
+ * =                          ui viewer handlers                              =
+ * ============================================================================
+ */
+static int preload_ui_viewer_main_eh(struct uretprobe_instance *ri,
+                             struct pt_regs *regs)
+{
+       struct process_data *pd;
+       struct us_ip *ip = container_of(ri->rp, struct us_ip, retprobe);
+       unsigned long vaddr = 0;
+       char __user *path = NULL;
+
+       preload_ui_viewer_init(ip);
+
+       pd = __get_process_data(ri->rp);
+
+       switch (preload_pd_get_ui_viewer_state(pd)) {
+       case NOT_LOADED:
+               /* jump to loader code if ready */
+               vaddr = preload_pd_get_loader_base(pd) +
+                       preload_debugfs_get_loader_offset();
+               if (vaddr) {
+                       /* save original regs state */
+                       __save_uregs(ri, regs);
+                       print_regs("UI VIEWER ORIG", regs, ri);
+
+                       path = preload_pd_get_ui_viewer_path(pd);
+
+                       /* set dlopen args: filename, flags */
+                       swap_set_arg(regs, 0, (unsigned long)path);
+                       swap_set_arg(regs, 1, 2 /* RTLD_NOW */);
+
+                       /* do the jump to dlopen */
+                       __prepare_ujump(ri, regs, vaddr);
+                       /* set new state */
+                       preload_pd_set_ui_viewer_state(pd, LOADING);
+               }
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static int preload_ui_viewer_main_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
+{
+       struct process_data *pd = __get_process_data(ri->rp);
+       struct us_ip *ip = container_of(ri->rp, struct us_ip, retprobe);
+       unsigned long vaddr = 0;
+
+       switch (preload_pd_get_ui_viewer_state(pd)) {
+       case LOADING:
+               vaddr = preload_pd_get_loader_base(pd) +
+                       preload_debugfs_get_loader_offset();
+               if (vaddr) {
+                       preload_pd_set_handle(pd,
+                               (void __user *)regs_return_value(regs));
+                       /* restore original regs state */
+                       __restore_uregs(ri, regs);
+                       print_regs("UI VIEWER REST", regs, ri);
+
+                       /* check if preloading is done */
+                       if (preload_pd_get_handle(pd)) {
+                               preload_pd_set_ui_viewer_state(pd, LOADED);
+                       } else {
+                               preload_pd_set_ui_viewer_state(pd, FAILED);
+                       }
+               }
+       default:
+               break;
+       }
+
+       preload_ui_viewer_exit(ip);
+
+       return 0;
+}
+
+
 static int preload_module_init(void)
 {
        int ret;
index 62f0bfd..3b1a573 100644 (file)
@@ -26,5 +26,7 @@ void preload_module_write_msg_exit(struct us_ip *ip);
 struct dentry *get_dentry(const char *filepath);
 void put_dentry(struct dentry *dentry);
 
+int preload_ui_viewer_data_set(const char *app_path, unsigned long main_addr);
+
 
 #endif /* __PRELOAD_MODULE_H__ */
index fcc2e6b..debd178 100644 (file)
 #include "preload_storage.h"
 #include "preload.h"
 
+
 struct process_data {
        enum preload_state_t state;
+       enum preload_state_t ui_viewer_state;
        unsigned long loader_base;
        unsigned long handlers_base;
+       unsigned long ui_viewer_base;
        unsigned long data_page;
+       unsigned long ui_viewer_offset;
        void __user *handle;
        long attempts;
        long refcount;
 };
 
 static struct bin_info *handlers_info;
+static struct bin_info *ui_viewer_info;
 
 
 
@@ -112,6 +117,38 @@ static inline void __set_refcount(struct process_data *pd, long refcount)
        pd->refcount = refcount;
 }
 
+static inline enum preload_state_t __get_ui_viewer_state(struct process_data *pd)
+{
+       return pd->ui_viewer_state;
+}
+
+static inline void __set_ui_viewer_state(struct process_data *pd,
+                                  enum preload_state_t state)
+{
+       pd->ui_viewer_state = state;
+}
+
+static inline void __set_ui_viewer_base(struct process_data *pd,
+                                       unsigned long addr)
+{
+       pd->ui_viewer_base = addr;
+}
+
+static inline unsigned long __get_ui_viewer_base(struct process_data *pd)
+{
+       return pd->ui_viewer_base;
+}
+
+static inline void __set_ui_viewer_offset(struct process_data *pd,
+                                         unsigned long offset)
+{
+       pd->ui_viewer_offset = offset;
+}
+
+static inline char __user *__get_ui_viewer_path(struct process_data *pd)
+{
+       return (char *)(pd->data_page + pd->ui_viewer_offset);
+}
 
 
 
@@ -123,6 +160,12 @@ static int __pd_create_on_demand(void)
                        return -EINVAL;
        }
 
+       if (ui_viewer_info == NULL) {
+               ui_viewer_info = preload_storage_get_ui_viewer_info();
+               if (ui_viewer_info == NULL)
+                       return -EINVAL;
+       }
+
        return 0;
 }
 
@@ -140,13 +183,47 @@ void preload_pd_set_state(struct process_data *pd, enum preload_state_t state)
 {
        if (pd == NULL) {
                printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__,
-               current->tgid, current->comm);
+                      current->tgid, current->comm);
                return;
        }
 
        __set_state(pd, state);
 }
 
+enum preload_state_t preload_pd_get_ui_viewer_state(struct process_data *pd)
+{
+       if (pd == NULL)
+               return 0;
+
+       return __get_ui_viewer_state(pd);
+}
+
+void preload_pd_set_ui_viewer_state(struct process_data *pd,
+                                   enum preload_state_t state)
+{
+       if (pd == NULL) {
+               printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__,
+                      current->tgid, current->comm);
+               return;
+       }
+
+       __set_ui_viewer_state(pd, state);
+}
+
+char __user *preload_pd_get_path(struct process_data *pd)
+{
+       char __user *path = __get_path(pd);
+
+       return path;
+}
+
+char __user *preload_pd_get_ui_viewer_path(struct process_data *pd)
+{
+       char __user *path = __get_ui_viewer_path(pd);
+
+       return path;
+}
+
 unsigned long preload_pd_get_loader_base(struct process_data *pd)
 {
        if (pd == NULL)
@@ -173,11 +250,30 @@ void preload_pd_set_handlers_base(struct process_data *pd, unsigned long vaddr)
        __set_handlers_base(pd, vaddr);
 }
 
+unsigned long preload_pd_get_ui_viewer_base(struct process_data *pd)
+{
+       if (pd == NULL)
+               return 0;
+
+       return __get_ui_viewer_base(pd);
+}
+
+void preload_pd_set_ui_viewer_base(struct process_data *pd, unsigned long vaddr)
+{
+       if (pd == NULL) {
+               printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__,
+                      current->tgid, current->comm);
+               return;
+       }
+
+       __set_ui_viewer_base(pd, vaddr);
+}
+
 void preload_pd_put_path(struct process_data *pd)
 {
        if (pd == NULL) {
                printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n", __LINE__,
-               current->tgid, current->comm);
+                      current->tgid, current->comm);
                return;
        }
 
@@ -187,15 +283,6 @@ void preload_pd_put_path(struct process_data *pd)
        __set_data_page(pd, 0);
 }
 
-char __user *preload_pd_get_path(struct process_data *pd)
-{
-       char __user *path = __get_path(pd);
-
-       return path;
-}
-
-
-
 void *preload_pd_get_handle(struct process_data *pd)
 {
        if (pd == NULL)
@@ -281,13 +368,15 @@ struct process_data *preload_pd_get(struct sspt_proc *proc)
        return (struct process_data *)proc->private_data;
 }
 
-static unsigned long make_preload_path(void)
+static unsigned long make_preload_path(unsigned long *offset)
 {
        unsigned long page = -EINVAL;
 
-       if (handlers_info) {
-               const char *path = handlers_info->path;
-               size_t len = strnlen(path, PATH_MAX);
+       if (handlers_info && ui_viewer_info) {
+               const char *probe_path = handlers_info->path;
+               size_t probe_len = strnlen(probe_path, PATH_MAX);
+               const char *ui_viewer_path = ui_viewer_info->path;
+               size_t ui_viewer_len = strnlen(ui_viewer_path, PATH_MAX);
 
                down_write(&current->mm->mmap_sem);
                page = swap_do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_WRITE,
@@ -300,8 +389,17 @@ static unsigned long make_preload_path(void)
                        goto out;
                }
 
-               /* set preload_library path */
-               if (copy_to_user((void __user *)page, path, len) != 0)
+               /* set preload_libraries paths */
+               if (copy_to_user((void __user *)page, probe_path,
+                                probe_len) != 0)
+                       printk(KERN_ERR PRELOAD_PREFIX
+                              "Cannot copy string to user!\n");
+
+               /* split paths with 0 value */
+               *offset = probe_len + 1;
+
+               if (copy_to_user((void __user *)(page + *offset),
+                                ui_viewer_path, ui_viewer_len) != 0)
                        printk(KERN_ERR PRELOAD_PREFIX
                               "Cannot copy string to user!\n");
        }
@@ -348,7 +446,7 @@ static void set_already_mapp(struct process_data *pd, struct mm_struct *mm)
 static struct process_data *do_create_pd(struct task_struct *task)
 {
        struct process_data *pd;
-       unsigned long page;
+       unsigned long page, offset = 0;
        int ret;
 
        ret = __pd_create_on_demand();
@@ -361,13 +459,14 @@ static struct process_data *do_create_pd(struct task_struct *task)
                goto create_pd_exit;
        }
 
-       page = make_preload_path();
+       page = make_preload_path(&offset);
        if (IS_ERR_VALUE(page)) {
                ret = (long)page;
                goto free_pd;
        }
 
        __set_data_page(pd, page);
+       __set_ui_viewer_offset(pd, offset);
        __set_attempts(pd, PRELOAD_MAX_ATTEMPTS);
        set_already_mapp(pd, task->mm);
 
@@ -416,4 +515,8 @@ void preload_pd_uninit(void)
        if (handlers_info)
                preload_storage_put_handlers_info(handlers_info);
        handlers_info = NULL;
+
+       if (ui_viewer_info)
+               preload_storage_put_ui_viewer_info(ui_viewer_info);
+       ui_viewer_info = NULL;
 }
index bff469d..31195bb 100644 (file)
@@ -17,10 +17,16 @@ struct process_data *preload_pd_get(struct sspt_proc *proc);
 
 enum preload_state_t preload_pd_get_state(struct process_data *pd);
 void preload_pd_set_state(struct process_data *pd, enum preload_state_t state);
+enum preload_state_t preload_pd_get_ui_viewer_state(struct process_data *pd);
+void preload_pd_set_ui_viewer_state(struct process_data *pd,
+                                   enum preload_state_t state);
 unsigned long preload_pd_get_loader_base(struct process_data *pd);
 void preload_pd_set_loader_base(struct process_data *pd, unsigned long vaddr);
 unsigned long preload_pd_get_handlers_base(struct process_data *pd);
 void preload_pd_set_handlers_base(struct process_data *pd, unsigned long vaddr);
+unsigned long preload_pd_get_ui_viewer_base(struct process_data *pd);
+void preload_pd_set_ui_viewer_base(struct process_data *pd,
+                                  unsigned long vaddr);
 void *preload_pd_get_handle(struct process_data *pd);
 void preload_pd_set_handle(struct process_data *pd, void __user *handle);
 
@@ -32,6 +38,7 @@ void preload_pd_dec_refs(struct process_data *pd);
 long preload_pd_get_refs(struct process_data *pd);
 
 char __user *preload_pd_get_path(struct process_data *pd);
+char __user *preload_pd_get_ui_viewer_path(struct process_data *pd);
 void preload_pd_put_path(struct process_data *pd);
 
 int preload_pd_init(void);
index 18c9585..255f8a9 100644 (file)
@@ -257,6 +257,7 @@ int register_preload_probes(void)
                return ret;
 
        ret = swap_register_probe_type(SWAP_WRITE_MSG, &write_msg_iface);
+
        return ret;
 }
 
index e6d1c5d..1c8db1a 100644 (file)
@@ -8,6 +8,7 @@
 #include "preload_storage.h"
 
 static struct bin_info __handlers_info = { NULL, NULL };
+static struct bin_info __ui_viewer_info = { NULL, NULL };
 static struct bin_info __linker_info = { NULL, NULL };
 static struct bin_info __libc_info;
 static struct bin_info __libpthread_info;
@@ -64,6 +65,57 @@ static inline void __drop_handlers_info(void)
        __handlers_info.dentry = NULL;
 }
 
+static inline struct bin_info *__get_ui_viewer_info(void)
+{
+       return &__ui_viewer_info;
+}
+
+static inline bool __check_ui_viewer_info(void)
+{
+       return (__ui_viewer_info.dentry != NULL); /* TODO */
+}
+
+static inline int __init_ui_viewer_info(char *path)
+{
+       struct dentry *dentry;
+       size_t len = strnlen(path, PATH_MAX);
+       int ret = 0;
+
+       __ui_viewer_info.path = kmalloc(len + 1, GFP_KERNEL);
+       if (__ui_viewer_info.path == NULL) {
+               ret = -ENOMEM;
+               goto init_ui_viewer_fail;
+       }
+
+       dentry = get_dentry(path);
+       if (!dentry) {
+               ret = -ENOENT;
+               goto init_ui_viewer_fail_free;
+       }
+
+       strncpy(__ui_viewer_info.path, path, len);
+       __ui_viewer_info.path[len] = '\0';
+       __ui_viewer_info.dentry = dentry;
+
+       return ret;
+
+init_ui_viewer_fail_free:
+       kfree(__ui_viewer_info.path);
+
+init_ui_viewer_fail:
+       return ret;
+}
+
+static inline void __drop_ui_viewer_info(void)
+{
+       kfree(__ui_viewer_info.path);
+       __ui_viewer_info.path = NULL;
+
+       if (__ui_viewer_info.dentry)
+               put_dentry(__ui_viewer_info.dentry);
+       __ui_viewer_info.dentry = NULL;
+}
+
 static inline struct bin_info *__get_linker_info(void)
 {
        return &__linker_info;
@@ -139,6 +191,25 @@ void preload_storage_put_handlers_info(struct bin_info *info)
 {
 }
 
+int preload_storage_set_ui_viewer_info(char *path)
+{
+       return __init_ui_viewer_info(path);
+}
+
+struct bin_info *preload_storage_get_ui_viewer_info(void)
+{
+       struct bin_info *info = __get_ui_viewer_info();
+
+       if (__check_ui_viewer_info())
+               return info;
+
+       return NULL;
+}
+
+void preload_storage_put_ui_viewer_info(struct bin_info *info)
+{
+}
+
 int preload_storage_set_linker_info(char *path)
 {
        return __init_linker_info(path);
@@ -243,5 +314,6 @@ void preload_storage_exit(void)
        __drop_libpthread_info();
        __drop_libc_info();
        __drop_handlers_info();
+       __drop_ui_viewer_info();
        __drop_linker_info();
 }
index 2ae1675..2afc186 100644 (file)
@@ -11,6 +11,10 @@ int preload_storage_set_handlers_info(char *path);
 struct bin_info *preload_storage_get_handlers_info(void);
 void preload_storage_put_handlers_info(struct bin_info *info);
 
+int preload_storage_set_ui_viewer_info(char *path);
+struct bin_info *preload_storage_get_ui_viewer_info(void);
+void preload_storage_put_ui_viewer_info(struct bin_info *info);
+
 int preload_storage_set_linker_info(char *path);
 struct bin_info *preload_storage_get_linker_info(void);
 void preload_storage_put_linker_info(struct bin_info *info);
index 5c764e8..559e44f 100644 (file)
@@ -232,7 +232,7 @@ static void urp_init(struct us_ip *ip)
        ip->retprobe.handler = urp_ret_handler;
        ip->retprobe.maxactive = 0;
        /* FIXME: make dynamic size field 'data_size' */
-       ip->retprobe.data_size = sizeof(void *);
+       ip->retprobe.data_size = 128;
 }
 
 static void urp_uninit(struct us_ip *ip)