[REFACTOR] Loader separated from preload 65/59065/4
authorAlexander Aksenov <a.aksenov@samsung.com>
Mon, 8 Feb 2016 17:50:37 +0000 (20:50 +0300)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Fri, 29 Apr 2016 13:35:35 +0000 (16:35 +0300)
Change-Id: I04159e8f3066ff8c5d0584661b91b6fd4219e7df
Signed-off-by: Alexander Aksenov <a.aksenov@samsung.com>
29 files changed:
Kbuild
loader/Kbuild [new file with mode: 0644]
loader/loader.h [new file with mode: 0644]
loader/loader_control.c [new file with mode: 0644]
loader/loader_control.h [new file with mode: 0644]
loader/loader_debugfs.c [new file with mode: 0644]
loader/loader_debugfs.h [new file with mode: 0644]
loader/loader_module.c [new file with mode: 0644]
loader/loader_module.h [new file with mode: 0644]
loader/loader_pd.c [moved from preload/preload_pd.c with 80% similarity]
loader/loader_pd.h [new file with mode: 0644]
loader/loader_storage.c [moved from preload/preload_storage.c with 54% similarity]
loader/loader_storage.h [new file with mode: 0644]
packaging/swap-modules.spec
preload/Kbuild
preload/preload_control.c
preload/preload_control.h
preload/preload_debugfs.c
preload/preload_debugfs.h
preload/preload_handlers.c [deleted file]
preload/preload_handlers.h [deleted file]
preload/preload_module.c
preload/preload_module.h
preload/preload_pd.h [deleted file]
preload/preload_probe.c
preload/preload_probe.h
preload/preload_storage.h [deleted file]
preload/preload_threads.c
preload/preload_threads.h

diff --git a/Kbuild b/Kbuild
index 3757b1d..473585c 100644 (file)
--- a/Kbuild
+++ b/Kbuild
@@ -13,6 +13,7 @@ obj-m := master/ \
          uprobe/ \
          us_manager/ \
          ks_features/ \
+         loader/ \
          sampler/ \
          energy/ \
          parser/ \
diff --git a/loader/Kbuild b/loader/Kbuild
new file mode 100644 (file)
index 0000000..f6cd9f7
--- /dev/null
@@ -0,0 +1,8 @@
+EXTRA_CFLAGS := $(extra_cflags)
+
+obj-m := swap_loader.o
+swap_loader-y := loader_module.o \
+                 loader_debugfs.o \
+                 loader_storage.o \
+                 loader_control.o \
+                 loader_pd.o
diff --git a/loader/loader.h b/loader/loader.h
new file mode 100644 (file)
index 0000000..92b4cb3
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __LOADER__
+#define __LOADER__
+
+#define LOADER_PREFIX "SWAP_LOADER: "
+#define LOADER_MAX_ATTEMPTS 10
+#define LOADER_DEFAULT_PERMS (S_IRUSR | S_IWUSR) /* u+rw */
+
+#endif /* __LOADER__ */
diff --git a/loader/loader_control.c b/loader/loader_control.c
new file mode 100644 (file)
index 0000000..a6d3be0
--- /dev/null
@@ -0,0 +1,214 @@
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/limits.h>
+#include <linux/list.h>
+
+#include "loader.h"
+#include "loader_control.h"
+#include "loader_module.h"
+
+struct bin_desc {
+       struct list_head list;
+       struct dentry *dentry;
+       char *filename;
+};
+
+struct list_desc {
+       struct list_head list;
+       rwlock_t lock;
+       int cnt;
+};
+
+static struct list_desc ignored = {
+       .list = LIST_HEAD_INIT(ignored.list),
+       .lock = __RW_LOCK_UNLOCKED(&ignored.lock),
+       .cnt = 0
+};
+
+static struct bin_desc *__alloc_binary(struct dentry *dentry, char *name,
+                                      int namelen)
+{
+       struct bin_desc *p = NULL;
+
+       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       if (!p)
+               return NULL;
+
+       INIT_LIST_HEAD(&p->list);
+       p->filename = kmalloc(namelen + 1, GFP_KERNEL);
+       if (!p->filename)
+               goto fail;
+       memcpy(p->filename, name, namelen);
+       p->filename[namelen] = '\0';
+       p->dentry = dentry;
+
+       return p;
+fail:
+       kfree(p);
+       return NULL;
+}
+
+static void __free_binary(struct bin_desc *p)
+{
+       kfree(p->filename);
+       kfree(p);
+}
+
+static void __free_ign_binaries(void)
+{
+       struct bin_desc *p, *n;
+       struct list_head rm_head;
+
+       INIT_LIST_HEAD(&rm_head);
+       write_lock(&ignored.lock);
+       list_for_each_entry_safe(p, n, &ignored.list, list) {
+               list_move(&p->list, &rm_head);
+       }
+       ignored.cnt = 0;
+       write_unlock(&ignored.lock);
+
+       list_for_each_entry_safe(p, n, &rm_head, list) {
+               list_del(&p->list);
+               put_dentry(p->dentry);
+               __free_binary(p);
+       }
+}
+
+static bool __check_dentry_already_exist(struct dentry *dentry)
+{
+       struct bin_desc *p;
+       bool ret = false;
+
+       read_lock(&ignored.lock);
+       list_for_each_entry(p, &ignored.list, list) {
+               if (p->dentry == dentry) {
+                       ret = true;
+                       goto out;
+               }
+       }
+out:
+       read_unlock(&ignored.lock);
+
+       return ret;
+}
+
+static int __add_ign_binary(struct dentry *dentry, char *filename)
+{
+       struct bin_desc *p;
+       size_t len;
+
+       if (__check_dentry_already_exist(dentry)) {
+               printk(LOADER_PREFIX "Binary already exist\n");
+               return EALREADY;
+       }
+
+       /* Filename should be < PATH_MAX */
+       len = strnlen(filename, PATH_MAX);
+       if (len == PATH_MAX)
+               return -EINVAL;
+
+       p = __alloc_binary(dentry, filename, len);
+       if (!p)
+               return -ENOMEM;
+
+       write_lock(&ignored.lock);
+       list_add_tail(&p->list, &ignored.list);
+       ignored.cnt++;
+       write_unlock(&ignored.lock);
+
+       return 0;
+}
+
+static unsigned int __get_ign_names(char ***filenames_p)
+{
+       unsigned int i, ret = 0;
+       struct bin_desc *p;
+       char **a = NULL;
+
+       read_lock(&ignored.lock);
+       if (ignored.cnt == 0)
+               goto out;
+
+       a = kmalloc(sizeof(*a) * ignored.cnt, GFP_KERNEL);
+       if (!a)
+               goto out;
+
+       i = 0;
+       list_for_each_entry(p, &ignored.list, list) {
+               if (i >= ignored.cnt)
+                       break;
+               a[i++] = p->filename;
+       }
+
+       *filenames_p = a;
+       ret = i;
+out:
+       read_unlock(&ignored.lock);
+       return ret;
+}
+
+
+
+int lc_add_ignored_binary(char *filename)
+{
+       struct dentry *dentry = get_dentry(filename);
+       int res = 0;
+
+       if (dentry == NULL)
+               return -EINVAL;
+
+       res = __add_ign_binary(dentry, filename);
+       if (res != 0)
+               put_dentry(dentry);
+
+       return res > 0 ? 0 : res;
+}
+
+int lc_clean_ignored_bins(void)
+{
+       __free_ign_binaries();
+
+       return 0;
+}
+
+unsigned int lc_get_ignored_names(char ***filenames_p)
+{
+       return __get_ign_names(filenames_p);
+}
+
+void lc_release_ignored_names(char ***filenames_p)
+{
+       kfree(*filenames_p);
+}
+
+bool lc_check_dentry_is_ignored(struct dentry *dentry)
+{
+       struct bin_desc *p;
+       bool ret = false;
+
+       if (dentry == NULL)
+               return false;
+
+       read_lock(&ignored.lock);
+
+       list_for_each_entry(p, &ignored.list, list) {
+               if (p->dentry == dentry) {
+                       ret = true;
+                       break;
+               }
+       }
+
+       read_unlock(&ignored.lock);
+
+       return ret;
+}
+
+int lc_init(void)
+{
+       return 0;
+}
+
+void lc_exit(void)
+{
+       __free_ign_binaries();
+}
diff --git a/loader/loader_control.h b/loader/loader_control.h
new file mode 100644 (file)
index 0000000..37988df
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef __LOADER_CONTROL_H__
+#define __LOADER_CONTROL_H__
+
+struct dentry;
+
+int lc_init(void);
+void lc_exit(void);
+
+int lc_add_ignored_binary(char *filename);
+int lc_clean_ignored_bins(void);
+
+unsigned int lc_get_ignored_names(char ***filenames_p);
+void lc_release_ignored_names(char ***filenames_p);
+
+bool lc_check_dentry_is_ignored(struct dentry *dentry);
+
+#endif /* __LOADER_CONTROL_H__ */
diff --git a/loader/loader_debugfs.c b/loader/loader_debugfs.c
new file mode 100644 (file)
index 0000000..58c7736
--- /dev/null
@@ -0,0 +1,456 @@
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/limits.h>
+#include <asm/uaccess.h>
+#include <master/swap_debugfs.h>
+#include "loader.h"
+#include "loader_debugfs.h"
+#include "loader_module.h"
+#include "loader_control.h"
+#include "loader_storage.h"
+
+static const char LOADER_FOLDER[] = "loader";
+static const char LOADER_LOADER[] = "loader";
+static const char LOADER_LOADER_OFFSET[] = "loader_offset";
+static const char LOADER_LOADER_PATH[] = "loader_path";
+static const char LOADER_IGNORED[] = "ignored_binaries";
+static const char LOADER_BINARIES_LIST[] = "bins_list";
+static const char LOADER_BINARIES_ADD[] = "bins_add";
+static const char LOADER_BINARIES_REMOVE[] = "bins_remove";
+static const char LOADER_CALLER[] = "caller";
+static const char LOADER_LINKER_DATA[] = "linker";
+static const char LOADER_LINKER_PATH[] = "linker_path";
+static const char LOADER_LINKER_R_DEBUG_OFFSET[] = "r_debug_offset";
+
+struct loader_info {
+       char *path;
+       unsigned long offset;
+       struct dentry *dentry;
+};
+
+static struct dentry *loader_root;
+static struct loader_info __loader_info;
+
+static unsigned long r_debug_offset = 0;
+static DEFINE_SPINLOCK(__dentry_lock);
+
+static inline void dentry_lock(void)
+{
+       spin_lock(&__dentry_lock);
+}
+
+static inline void dentry_unlock(void)
+{
+       spin_unlock(&__dentry_lock);
+}
+
+
+static void set_loader_file(char *path)
+{
+       __loader_info.path = path;
+       dentry_lock();
+       __loader_info.dentry = get_dentry(__loader_info.path);
+       dentry_unlock();
+}
+
+struct dentry *ld_get_loader_dentry(void)
+{
+       struct dentry *dentry;
+
+       dentry_lock();
+       dentry = __loader_info.dentry;
+       dentry_unlock();
+
+       return dentry;
+}
+
+unsigned long ld_get_loader_offset(void)
+{
+       /* TODO Think about sync */
+       return __loader_info.offset;
+}
+
+static void clean_loader_info(void)
+{
+       if (__loader_info.path != NULL)
+               kfree(__loader_info.path);
+       __loader_info.path = NULL;
+
+       dentry_lock();
+       if (__loader_info.dentry != NULL)
+               put_dentry(__loader_info.dentry);
+
+       __loader_info.dentry = NULL;
+       __loader_info.offset = 0;
+
+       dentry_unlock();
+}
+
+struct dentry *debugfs_create_ptr(const char *name, mode_t mode,
+                                 struct dentry *parent,
+                                 unsigned long *value)
+{
+       struct dentry *dentry;
+
+#if BITS_PER_LONG == 32
+       dentry = debugfs_create_x32(name, mode, parent, (u32 *)value);
+#elif BITS_PER_LONG == 64
+       dentry = debugfs_create_x64(name, mode, parent, (u64 *)value);
+#else
+#error Unsupported BITS_PER_LONG value
+#endif
+
+       return dentry;
+}
+
+
+/* ===========================================================================
+ * =                              LOADER PATH                                =
+ * ===========================================================================
+ */
+
+static ssize_t loader_path_write(struct file *file, const char __user *buf,
+                                size_t len, loff_t *ppos)
+{
+       ssize_t ret;
+       char *path;
+
+       if (loader_module_is_running())
+               return -EBUSY;
+
+       clean_loader_info();
+
+       path = kmalloc(len, GFP_KERNEL);
+       if (path == NULL) {
+               return -ENOMEM;
+       }
+
+       if (copy_from_user(path, buf, len)) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       path[len - 1] = '\0';
+       set_loader_file(path);
+
+       ret = lc_add_ignored_binary(path);
+       if (ret < 0) {
+               printk(LOADER_PREFIX "Cannot add loader %s to ignored list\n", path);
+               goto err;
+       }
+
+       ret = len;
+
+       return ret;
+err:
+       kfree(path);
+       return ret;
+}
+
+
+static const struct file_operations loader_path_file_ops = {
+       .owner = THIS_MODULE,
+       .write = loader_path_write,
+};
+
+
+/* ===========================================================================
+ * =                                BIN PATH                                 =
+ * ===========================================================================
+ */
+
+static ssize_t bin_add_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 bin_add_write_out;
+       }
+
+       if (copy_from_user(path, buf, len)) {
+               ret = -EINVAL;
+               goto bin_add_write_out;
+       }
+
+       path[len - 1] = '\0';
+
+       ret = lc_add_ignored_binary(path);
+       if (ret != 0) {
+               printk(LOADER_PREFIX "Cannot add binary %s\n", path);
+               ret = -EINVAL;
+               goto bin_add_write_out;
+       }
+
+       ret = len;
+
+bin_add_write_out:
+       kfree(path);
+
+       return ret;
+}
+
+static ssize_t bin_remove_write(struct file *file, const char __user *buf,
+                             size_t len, loff_t *ppos)
+{
+       ssize_t ret;
+
+       ret = lc_clean_ignored_bins();
+       if (ret != 0) {
+               printk(LOADER_PREFIX "Error during clean!\n");
+               ret = -EINVAL;
+               goto bin_remove_write_out;
+       }
+
+       ret = len;
+
+bin_remove_write_out:
+       return ret;
+}
+
+static ssize_t bin_list_read(struct file *file, char __user *usr_buf,
+                                size_t count, loff_t *ppos)
+{
+       unsigned int i;
+       unsigned int files_cnt = 0;
+       ssize_t len = 0, tmp, ret = 0;
+       char **filenames = NULL;
+       char *buf = NULL;
+       char *ptr = NULL;
+
+       files_cnt = lc_get_ignored_names(&filenames);
+       if (files_cnt == 0) {
+               printk(LOADER_PREFIX "Cannot read binaries names!\n");
+               ret = 0;
+               goto bin_list_read_fail;
+       }
+
+       for (i = 0; i < files_cnt; i++)
+               len += strlen(filenames[i]);
+
+       buf = kmalloc(len + files_cnt, GFP_KERNEL);
+       if (buf == NULL) {
+               ret = 0;
+               goto bin_list_read_fail;
+       }
+
+       ptr = buf;
+
+       for (i = 0; i < files_cnt; i++) {
+               tmp = strlen(filenames[i]);
+               memcpy(ptr, filenames[i], tmp);
+               ptr += tmp;
+               *ptr = '\n';
+               ptr += 1;
+       }
+
+       ret = simple_read_from_buffer(usr_buf, count, ppos, buf, len);
+
+       kfree(buf);
+
+bin_list_read_fail:
+       lc_release_ignored_names(&filenames);
+
+       return ret;
+}
+
+static const struct file_operations bin_list_file_ops = {
+       .owner = THIS_MODULE,
+       .read = bin_list_read
+};
+
+static const struct file_operations bin_add_file_ops = {
+       .owner = THIS_MODULE,
+       .write = bin_add_write,
+};
+
+static const struct file_operations bin_remove_file_ops = {
+       .owner = THIS_MODULE,
+       .write = bin_remove_write,
+};
+
+
+/* ===========================================================================
+ * =                            LINKER PATH                                  =
+ * ===========================================================================
+ */
+
+
+static ssize_t linker_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 linker_path_write_out;
+       }
+
+       if (copy_from_user(path, buf, len)) {
+               ret = -EINVAL;
+               goto linker_path_write_out;
+       }
+
+       path[len - 1] = '\0';
+
+       if (ls_set_linker_info(path) != 0) {
+               printk(LOADER_PREFIX "Cannot set linker path %s\n", path);
+               ret = -EINVAL;
+               goto linker_path_write_out;
+       }
+
+       ret = lc_add_ignored_binary(path);
+       if (ret < 0) {
+               printk(LOADER_PREFIX "Cannot add linker %s to ignored list\n", path);
+               goto linker_path_write_out;
+       }
+
+       ret = len;
+
+linker_path_write_out:
+       kfree(path);
+
+       return ret;
+}
+
+static const struct file_operations linker_path_file_ops = {
+       .owner = THIS_MODULE,
+       .write = linker_path_write,
+};
+
+
+
+
+
+unsigned long ld_r_debug_offset(void)
+{
+       return r_debug_offset;
+}
+
+int ld_init(void)
+{
+       struct dentry *swap_dentry, *root, *loader, *open_p, *lib_path,
+                 *ignored_path, *linker_dir, *linker_path,
+                 *linker_offset, *ignored_list,
+                 *ignored_add, *ignored_remove;
+       int ret;
+
+       ret = -ENODEV;
+       if (!debugfs_initialized())
+               goto fail;
+
+       ret = -ENOENT;
+       swap_dentry = swap_debugfs_getdir();
+       if (!swap_dentry)
+               goto fail;
+
+       ret = -ENOMEM;
+       root = debugfs_create_dir(LOADER_FOLDER, swap_dentry);
+       if (IS_ERR_OR_NULL(root))
+               goto fail;
+
+       loader_root = root;
+
+       loader = debugfs_create_dir(LOADER_LOADER, root);
+       if (IS_ERR_OR_NULL(root)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
+       open_p = debugfs_create_ptr(LOADER_LOADER_OFFSET, LOADER_DEFAULT_PERMS,
+                                   loader, &__loader_info.offset);
+       if (IS_ERR_OR_NULL(open_p)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
+       lib_path = debugfs_create_file(LOADER_LOADER_PATH, LOADER_DEFAULT_PERMS,
+                                      loader, NULL, &loader_path_file_ops);
+       if (IS_ERR_OR_NULL(lib_path)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
+       ignored_path = debugfs_create_dir(LOADER_IGNORED, root);
+       if (IS_ERR_OR_NULL(ignored_path)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
+       ignored_list = debugfs_create_file(LOADER_BINARIES_LIST,
+                                          LOADER_DEFAULT_PERMS, ignored_path,
+                                          NULL, &bin_list_file_ops);
+       if (IS_ERR_OR_NULL(ignored_list)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
+       ignored_add = debugfs_create_file(LOADER_BINARIES_ADD,
+                                         LOADER_DEFAULT_PERMS, ignored_path, NULL,
+                                         &bin_add_file_ops);
+       if (IS_ERR_OR_NULL(ignored_add)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
+       ignored_remove = debugfs_create_file(LOADER_BINARIES_REMOVE,
+                                            LOADER_DEFAULT_PERMS, ignored_path, NULL,
+                                            &bin_remove_file_ops);
+       if (IS_ERR_OR_NULL(ignored_remove)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
+       linker_dir = debugfs_create_dir(LOADER_LINKER_DATA, root);
+       if (IS_ERR_OR_NULL(linker_dir)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
+       linker_path = debugfs_create_file(LOADER_LINKER_PATH,
+                                         LOADER_DEFAULT_PERMS, linker_dir, NULL,
+                                         &linker_path_file_ops);
+       if (IS_ERR_OR_NULL(linker_path)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
+       linker_offset = debugfs_create_ptr(LOADER_LINKER_R_DEBUG_OFFSET,
+                                          LOADER_DEFAULT_PERMS, linker_dir,
+                                          &r_debug_offset);
+       if (IS_ERR_OR_NULL(linker_offset)) {
+               ret = -ENOMEM;
+               goto remove;
+       }
+
+       return 0;
+
+remove:
+
+       debugfs_remove_recursive(root);
+
+fail:
+       printk(LOADER_PREFIX "Debugfs initialization failure: %d\n", ret);
+
+       return ret;
+}
+
+void ld_exit(void)
+{
+       if (loader_root)
+               debugfs_remove_recursive(loader_root);
+       loader_root = NULL;
+
+       loader_module_set_not_ready();
+       clean_loader_info();
+}
diff --git a/loader/loader_debugfs.h b/loader/loader_debugfs.h
new file mode 100644 (file)
index 0000000..f07b6f0
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __LOADER_DEBUGFS_H__
+#define __LOADER_DEBUGFS_H__
+
+struct dentry;
+
+int ld_init(void);
+void ld_exit(void);
+
+struct dentry *ld_get_loader_dentry(void);
+unsigned long ld_get_loader_offset(void);
+
+unsigned long ld_r_debug_offset(void);
+
+#endif /* __LOADER_DEBUGFS_H__ */
diff --git a/loader/loader_module.c b/loader/loader_module.c
new file mode 100644 (file)
index 0000000..1680311
--- /dev/null
@@ -0,0 +1,648 @@
+#include <linux/module.h>
+#include <linux/dcache.h>
+#include <linux/namei.h>
+#include <linux/mman.h>
+#include <linux/err.h>
+#include <linux/types.h>
+#include <kprobe/swap_kprobes.h>
+#include <kprobe/swap_kprobes_deps.h>
+#include <us_manager/sspt/sspt_proc.h>
+#include <us_manager/sspt/sspt_ip.h>
+#include <us_manager/callbacks.h>
+#include <writer/kernel_operations.h>
+#include <master/swap_initializer.h>
+#include "loader.h"
+#include "loader_debugfs.h"
+#include "loader_module.h"
+#include "loader_storage.h"
+#include "loader_control.h"
+#include "loader_pd.h"
+
+
+struct us_priv {
+       struct pt_regs regs;
+       unsigned long arg0;
+       unsigned long arg1;
+       unsigned long raddr;
+       unsigned long origin;
+};
+
+static atomic_t dentry_balance = ATOMIC_INIT(0);
+
+enum loader_status_t {
+       SWAP_LOADER_NOT_READY = 0,
+       SWAP_LOADER_READY = 1,
+       SWAP_LOADER_RUNNING = 2
+};
+
+static enum loader_status_t __loader_status = SWAP_LOADER_NOT_READY;
+
+static int __loader_cbs_start_h = -1;
+static int __loader_cbs_stop_h = -1;
+
+
+static struct dentry *__get_dentry(struct dentry *dentry)
+{
+       atomic_inc(&dentry_balance);
+       return dget(dentry);
+}
+
+
+
+bool loader_module_is_running(void)
+{
+       if (__loader_status == SWAP_LOADER_RUNNING)
+               return true;
+
+       return false;
+}
+
+bool loader_module_is_ready(void)
+{
+       if (__loader_status == SWAP_LOADER_READY)
+               return true;
+
+       return false;
+}
+
+bool loader_module_is_not_ready(void)
+{
+       if (__loader_status == SWAP_LOADER_NOT_READY)
+               return true;
+
+       return false;
+}
+
+void loader_module_set_ready(void)
+{
+       __loader_status = SWAP_LOADER_READY;
+}
+
+void loader_module_set_running(void)
+{
+       __loader_status = SWAP_LOADER_RUNNING;
+}
+
+void loader_module_set_not_ready(void)
+{
+       __loader_status = SWAP_LOADER_NOT_READY;
+}
+
+struct dentry *get_dentry(const char *filepath)
+{
+       struct path path;
+       struct dentry *dentry = NULL;
+
+       if (kern_path(filepath, LOOKUP_FOLLOW, &path) == 0) {
+               dentry = __get_dentry(path.dentry);
+               path_put(&path);
+       }
+
+       return dentry;
+}
+
+void put_dentry(struct dentry *dentry)
+{
+       atomic_dec(&dentry_balance);
+       dput(dentry);
+}
+
+static inline void __prepare_ujump(struct uretprobe_instance *ri,
+                                  struct pt_regs *regs,
+                                  unsigned long vaddr)
+{
+#ifdef CONFIG_ARM
+       ri->preload.use = true;
+       ri->preload.thumb = !!thumb_mode(regs);
+#endif /* CONFIG_ARM */
+
+       swap_set_instr_ptr(regs, vaddr);
+}
+
+static inline int __push(struct pt_regs *regs, void *buf, size_t len)
+{
+       unsigned long sp = swap_get_stack_ptr(regs) - len;
+
+       sp = PTR_ALIGN(sp, sizeof(unsigned long));
+       if (copy_to_user((void __user *)sp, buf, len))
+               return -EIO;
+       swap_set_stack_ptr(regs, sp);
+
+       return 0;
+}
+
+static inline void __save_uregs(struct uretprobe_instance *ri,
+                               struct pt_regs *regs)
+{
+       struct us_priv *priv = (struct us_priv *)ri->data;
+
+       memcpy(ri->data, regs, sizeof(*regs));
+       priv->arg0 = swap_get_arg(regs, 0);
+       priv->arg1 = swap_get_arg(regs, 1);
+       priv->raddr = swap_get_ret_addr(regs);
+}
+
+static inline void __restore_uregs(struct uretprobe_instance *ri,
+                                  struct pt_regs *regs)
+{
+       struct us_priv *priv = (struct us_priv *)ri->data;
+
+       memcpy(regs, ri->data, sizeof(*regs));
+       swap_set_arg(regs, 0, priv->arg0);
+       swap_set_arg(regs, 1, priv->arg1);
+       swap_set_ret_addr(regs, priv->raddr);
+#ifndef CONFIG_ARM
+       /* need to do it only on x86 */
+       regs->EREG(ip) -= 1;
+#endif /* !CONFIG_ARM */
+       /* we have just restored the registers => no need to do it in
+        * trampoline_uprobe_handler */
+       ri->ret_addr = NULL;
+}
+
+static inline void print_regs(const char *prefix, struct pt_regs *regs,
+                             struct uretprobe_instance *ri, struct hd_t *hd)
+{
+       struct dentry *dentry = lpd_get_dentry(hd);
+
+#ifdef CONFIG_ARM
+       printk(LOADER_PREFIX "%s[%d/%d] %s (%d) %s addr(%08lx), "
+              "r0(%08lx), r1(%08lx), r2(%08lx), r3(%08lx), "
+              "r4(%08lx), r5(%08lx), r6(%08lx), r7(%08lx), "
+              "sp(%08lx), lr(%08lx), pc(%08lx)\n",
+              current->comm, current->tgid, current->pid,
+              dentry != NULL ? (char *)(dentry->d_name.name) :
+                               (char *)("NULL"),
+              (int)lpd_get_state(hd),
+              prefix, (unsigned long)ri->rp->up.addr,
+              regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3,
+              regs->ARM_r4, regs->ARM_r5, regs->ARM_r6, regs->ARM_r7,
+              regs->ARM_sp, regs->ARM_lr, regs->ARM_pc);
+#else /* !CONFIG_ARM */
+       printk(LOADER_PREFIX "%s[%d/%d] %s (%d) %s addr(%08lx), "
+              "ip(%08lx), arg0(%08lx), arg1(%08lx), raddr(%08lx)\n",
+              current->comm, current->tgid, current->pid,
+              dentry != NULL ? (char *)(dentry->d_name.name) :
+                               (char *)("NULL"),
+              (int)lpd_get_state(hd),
+              prefix, (unsigned long)ri->rp->up.addr,
+              regs->EREG(ip), swap_get_arg(regs, 0), swap_get_arg(regs, 1),
+              swap_get_ret_addr(regs));
+#endif /* CONFIG_ARM */
+}
+
+static inline unsigned long __get_r_debug_off(struct vm_area_struct *linker_vma)
+{
+       unsigned long start_addr;
+       unsigned long offset = ld_r_debug_offset();
+
+       if (linker_vma == NULL)
+               return 0;
+
+       start_addr = linker_vma->vm_start;
+
+       return (offset ? start_addr + offset : 0);
+}
+
+static struct vm_area_struct *__get_linker_vma(struct task_struct *task)
+{
+       struct vm_area_struct *vma = NULL;
+       struct bin_info *ld_info;
+
+       ld_info = ls_get_linker_info();
+       if (ld_info == NULL) {
+               printk(LOADER_PREFIX "Cannot get linker info [%u %u %s]!\n",
+                      task->tgid, task->pid, task->comm);
+               return NULL;
+       }
+
+       for (vma = task->mm->mmap; vma; vma = vma->vm_next) {
+               if (vma->vm_file && vma->vm_flags & VM_EXEC
+                   && vma->vm_file->f_dentry == ld_info->dentry) {
+                               ls_put_linker_info(ld_info);
+                               return vma;
+               }
+       }
+
+       ls_put_linker_info(ld_info);
+       return NULL;
+}
+
+static inline struct vm_area_struct *__get_vma_by_addr(struct task_struct *task,
+                                                       unsigned long caller_addr)
+{
+       struct vm_area_struct *vma = NULL;
+
+       if (task->mm == NULL)
+               return NULL;
+       vma = find_vma_intersection(task->mm, caller_addr, caller_addr + 1);
+
+       return vma;
+}
+
+
+
+
+
+
+
+
+
+static bool __is_proc_mmap_mappable(struct task_struct *task)
+{
+       struct vm_area_struct *linker_vma = __get_linker_vma(task);
+       struct sspt_proc *proc;
+       unsigned long r_debug_addr;
+       unsigned int state;
+       enum { r_state_offset = sizeof(int) + sizeof(void *) + sizeof(long) };
+
+       if (linker_vma == NULL)
+               return false;
+
+       r_debug_addr = __get_r_debug_off(linker_vma);
+       if (r_debug_addr == 0)
+               return false;
+
+       r_debug_addr += r_state_offset;
+       proc = sspt_proc_get_by_task(task);
+       if (proc) {
+               proc->r_state_addr = r_debug_addr;
+               sspt_proc_put(proc);
+       }
+
+       if (get_user(state, (unsigned long *)r_debug_addr))
+               return false;
+
+       return !state;
+}
+
+static bool __should_we_load_handlers(struct task_struct *task,
+                                        struct pt_regs *regs)
+{
+       unsigned long caller_addr = get_regs_ret_func(regs);
+       struct vm_area_struct *cvma = __get_vma_by_addr(current, caller_addr);
+
+       if (!__is_proc_mmap_mappable(task) ||
+           ((cvma != NULL) && (cvma->vm_file != NULL) &&
+           (cvma->vm_file->f_path.dentry != NULL) &&
+           lc_check_dentry_is_ignored(cvma->vm_file->f_path.dentry)))
+               return false;
+
+       return true;
+}
+
+
+
+
+
+struct mmap_priv {
+       struct dentry *dentry;
+};
+
+static inline bool check_prot(unsigned long prot)
+{
+       return !!((prot & PROT_READ) && (prot & PROT_EXEC));
+}
+
+static int mmap_entry_handler(struct kretprobe_instance *ri,
+                             struct pt_regs *regs)
+{
+       struct file *file = (struct file *)swap_get_karg(regs, 0);
+       unsigned long prot = swap_get_karg(regs, 3);
+       struct mmap_priv *priv = (struct mmap_priv *)ri->data;
+       struct task_struct *task = current->group_leader;
+       struct dentry *dentry, *loader_dentry;
+       struct pd_t *pd;
+       struct hd_t *hd;
+       struct sspt_proc *proc;
+
+       priv->dentry = NULL;
+       if (!check_prot(prot))
+               return 0;
+
+       if (!file)
+               return 0;
+
+       dentry = file->f_dentry;
+       if (dentry == NULL)
+               return 0;
+
+       loader_dentry = ld_get_loader_dentry();
+       if (dentry == loader_dentry) {
+               priv->dentry = loader_dentry;
+               return 0;
+       }
+
+       proc = sspt_proc_get_by_task(task);
+       if (!proc)
+               return 0;
+
+       pd = lpd_get(proc);
+       if (pd == NULL) {
+               printk(LOADER_PREFIX "%d: No process data! Current %d %s\n",
+                      __LINE__, current->tgid, current->comm);
+               return 0;
+       }
+
+       hd = lpd_get_hd(pd, dentry);
+       if (hd != NULL)
+               priv->dentry = lpd_get_dentry(hd);
+
+       return 0;
+}
+
+static int mmap_ret_handler(struct kretprobe_instance *ri,
+                           struct pt_regs *regs)
+{
+       struct mmap_priv *priv = (struct mmap_priv *)ri->data;
+       struct task_struct *task = current->group_leader;
+       struct pd_t *pd;
+       struct hd_t *hd;
+       struct sspt_proc *proc;
+       struct dentry *loader_dentry;
+       unsigned long vaddr;
+
+       if (!task->mm)
+               return 0;
+
+       if (priv->dentry == NULL)
+               return 0;
+
+       vaddr = (unsigned long)regs_return_value(regs);
+       if (IS_ERR_VALUE(vaddr))
+               return 0;
+
+       proc = sspt_proc_get_by_task(task);
+       if (!proc)
+               return 0;
+
+       pd = lpd_get(proc);
+       if (pd == NULL) {
+               printk(LOADER_PREFIX "%d: No process data! Current %d %s\n",
+                      __LINE__, current->tgid, current->comm);
+               return 0;
+       }
+
+       loader_dentry = ld_get_loader_dentry();
+       if (priv->dentry == loader_dentry)
+               lpd_set_loader_base(pd, vaddr);
+
+
+       hd = lpd_get_hd(pd, priv->dentry);
+       if (hd != NULL)
+               lpd_set_handlers_base(hd, vaddr);
+
+       return 0;
+}
+
+static struct kretprobe mmap_rp = {
+       .kp.symbol_name = "do_mmap_pgoff",
+       .data_size = sizeof(struct mmap_priv),
+       .entry_handler = mmap_entry_handler,
+       .handler = mmap_ret_handler
+};
+
+static void loader_start_cb(void)
+{
+       int res;
+
+       res = swap_register_kretprobe(&mmap_rp);
+       if (res != 0)
+               printk(KERN_ERR LOADER_PREFIX "Registering do_mmap_pgoff probe failed\n");
+}
+
+static void loader_stop_cb(void)
+{
+       swap_unregister_kretprobe(&mmap_rp);
+}
+
+static unsigned long __not_loaded_entry(struct uretprobe_instance *ri,
+                                       struct pt_regs *regs,
+                                       struct pd_t *pd, struct hd_t *hd)
+{
+       char __user *path = NULL;
+       unsigned long vaddr = 0;
+       unsigned long base;
+
+       /* if linker is still doing its work, we do nothing */
+       if (!__should_we_load_handlers(current, regs))
+               return 0;
+
+       base = lpd_get_loader_base(pd);
+       if (base == 0)
+               return 0;   /* loader isn't mapped */
+
+       /* jump to loader code if ready */
+       vaddr = base + ld_get_loader_offset();
+       if (vaddr) {
+               /* save original regs state */
+               __save_uregs(ri, regs);
+               print_regs("ORIG", regs, ri, hd);
+
+               path = lpd_get_path(pd, hd);
+
+               /* set dlopen args: filename, flags */
+               swap_set_arg(regs, 0, (unsigned long)path/*swap_get_stack_ptr(regs)*/);
+               swap_set_arg(regs, 1, 2 /* RTLD_NOW */);
+
+               /* do the jump to dlopen */
+               __prepare_ujump(ri, regs, vaddr);
+               /* set new state */
+               lpd_set_state(hd, LOADING);
+       }
+
+       return vaddr;
+}
+
+static void __loading_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
+                         struct pd_t *pd, struct hd_t *hd)
+{
+       struct us_priv *priv = (struct us_priv *)ri->data;
+       unsigned long vaddr = 0;
+
+       /* check if loading has been completed */
+       vaddr = lpd_get_loader_base(pd) +
+               ld_get_loader_offset();
+       if (vaddr && (priv->origin == vaddr)) {
+               lpd_set_handle(hd,
+                                     (void __user *)regs_return_value(regs));
+
+               /* restore original regs state */
+               __restore_uregs(ri, regs);
+               print_regs("REST", regs, ri, hd);
+               /* check if loading done */
+
+               if (lpd_get_handle(hd)) {
+                       lpd_set_state(hd, LOADED);
+               } else {
+                       lpd_dec_attempts(hd);
+                       lpd_set_state(hd, FAILED);
+               }
+       }
+}
+
+static void __failed_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
+                        struct pd_t *pd, struct hd_t *hd)
+{
+       if (lpd_get_attempts(hd))
+               lpd_set_state(hd, NOT_LOADED);
+}
+
+
+
+unsigned long loader_not_loaded_entry(struct uretprobe_instance *ri,
+                                      struct pt_regs *regs, struct pd_t *pd,
+                                      struct hd_t *hd)
+{
+       return __not_loaded_entry(ri, regs, pd, hd);
+}
+EXPORT_SYMBOL_GPL(loader_not_loaded_entry);
+
+void loader_loading_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
+                        struct pd_t *pd, struct hd_t *hd)
+{
+       __loading_ret(ri, regs, pd, hd);
+}
+EXPORT_SYMBOL_GPL(loader_loading_ret);
+
+void loader_failed_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
+                       struct pd_t *pd, struct hd_t *hd)
+{
+       __failed_ret(ri, regs, pd, hd);
+}
+EXPORT_SYMBOL_GPL(loader_failed_ret);
+
+void loader_module_prepare_ujump(struct uretprobe_instance *ri,
+                                 struct pt_regs *regs, unsigned long addr)
+{
+       __prepare_ujump(ri, regs, addr);
+}
+EXPORT_SYMBOL_GPL(loader_module_prepare_ujump);
+
+void loader_set_rp_data_size(struct uretprobe *rp)
+{
+       rp->data_size = sizeof(struct us_priv);
+}
+EXPORT_SYMBOL_GPL(loader_set_rp_data_size);
+
+void loader_set_priv_origin(struct uretprobe_instance *ri, unsigned long addr)
+{
+       struct us_priv *priv = (struct us_priv *)ri->data;
+
+       priv->origin = addr;
+}
+EXPORT_SYMBOL_GPL(loader_set_priv_origin);
+
+unsigned long loader_get_priv_origin(struct uretprobe_instance *ri)
+{
+       struct us_priv *priv = (struct us_priv *)ri->data;
+
+       return priv->origin;
+}
+EXPORT_SYMBOL_GPL(loader_get_priv_origin);
+
+
+int loader_set(void)
+{
+       if (loader_module_is_running())
+               return -EBUSY;
+
+       return 0;
+}
+
+void loader_unset(void)
+{
+       swap_unregister_kretprobe(&mmap_rp);
+       /*module_put(THIS_MODULE);*/
+       loader_module_set_not_ready();
+}
+
+int loader_add_handler(char *path)
+{
+       return ls_add_handler(path);
+}
+EXPORT_SYMBOL_GPL(loader_add_handler);
+
+
+static int loader_module_init(void)
+{
+       int ret;
+
+       ret = ld_init();
+       if (ret)
+               goto out_err;
+
+       ret = ls_init();
+       if (ret)
+               goto exit_debugfs;
+
+       ret = lpd_init();
+       if (ret)
+               goto exit_storage;
+
+       /* TODO do not forget to remove set (it is just for debugging) */
+       ret = loader_set();
+       if (ret)
+               goto exit_pd;
+
+       ret = lc_init();
+       if (ret)
+               goto exit_set;
+
+       __loader_cbs_start_h = us_manager_reg_cb(START_CB, loader_start_cb);
+       if (__loader_cbs_start_h < 0)
+               goto exit_start_cb;
+
+       __loader_cbs_stop_h = us_manager_reg_cb(STOP_CB, loader_stop_cb);
+       if (__loader_cbs_stop_h < 0)
+               goto exit_stop_cb;
+
+       return 0;
+
+exit_stop_cb:
+       us_manager_unreg_cb(__loader_cbs_start_h);
+
+exit_start_cb:
+       lc_exit();
+
+exit_set:
+       loader_unset();
+
+exit_pd:
+       lpd_uninit();
+
+exit_storage:
+       ls_exit();
+
+exit_debugfs:
+       ld_exit();
+
+out_err:
+       return ret;
+}
+
+static void loader_module_exit(void)
+{
+       int balance;
+
+       us_manager_unreg_cb(__loader_cbs_start_h);
+       us_manager_unreg_cb(__loader_cbs_stop_h);
+       lc_exit();
+       loader_unset();
+       lpd_uninit();
+       ls_exit();
+       ld_exit();
+
+       balance = atomic_read(&dentry_balance);
+       atomic_set(&dentry_balance, 0);
+
+       WARN(balance, "Bad GET/PUT dentry balance: %d\n", balance);
+}
+
+SWAP_LIGHT_INIT_MODULE(NULL, loader_module_init, loader_module_exit,
+                      NULL, NULL);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SWAP Loader Module");
+MODULE_AUTHOR("Vasiliy Ulyanov <v.ulyanov@samsung.com>"
+              "Alexander Aksenov <a.aksenov@samsung.com>");
diff --git a/loader/loader_module.h b/loader/loader_module.h
new file mode 100644 (file)
index 0000000..df5da70
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef __LOADER_MODULE_H__
+#define __LOADER_MODULE_H__
+
+#include <linux/types.h>
+
+struct dentry;
+struct pd_t;
+struct hd_t;
+struct uretprobe;
+struct uretprobe_instance;
+
+bool loader_module_is_ready(void);
+bool loader_module_is_running(void);
+bool loader_module_is_not_ready(void);
+void loader_module_set_ready(void);
+void loader_module_set_running(void);
+void loader_module_set_not_ready(void);
+
+struct dentry *get_dentry(const char *filepath);
+void put_dentry(struct dentry *dentry);
+
+void loader_module_prepare_ujump(struct uretprobe_instance *ri,
+                                 struct pt_regs *regs, unsigned long addr);
+
+unsigned long loader_not_loaded_entry(struct uretprobe_instance *ri,
+                                      struct pt_regs *regs, struct pd_t *pd,
+                                      struct hd_t *hd);
+void loader_loading_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
+                        struct pd_t *pd, struct hd_t *hd);
+void loader_failed_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
+                       struct pd_t *pd, struct hd_t *hd);
+
+void loader_set_rp_data_size(struct uretprobe *rp);
+void loader_set_priv_origin(struct uretprobe_instance *ri, unsigned long addr);
+unsigned long loader_get_priv_origin(struct uretprobe_instance *ri);
+int loader_add_handler(char *path);
+
+
+#endif /* __LOADER_MODULE_H__ */
similarity index 80%
rename from preload/preload_pd.c
rename to loader/loader_pd.c
index 62c242d..beb5c54 100644 (file)
@@ -8,11 +8,10 @@
 #include <linux/list.h>
 #include <us_manager/us_manager_common.h>
 #include <us_manager/sspt/sspt_proc.h>
-#include "preload_pd.h"
-#include "preload_threads.h"
-#include "preload_debugfs.h"
-#include "preload_storage.h"
-#include "preload.h"
+#include "loader_pd.h"
+#include "loader_debugfs.h"
+#include "loader_storage.h"
+#include "loader.h"
 
 struct pd_t {
        unsigned long loader_base;
@@ -136,7 +135,7 @@ static struct pd_t *__create_pd(void)
                            MAP_ANONYMOUS | MAP_PRIVATE, 0);
        up_write(&current->mm->mmap_sem);
        if (IS_ERR_VALUE(page)) {
-               printk(KERN_ERR PRELOAD_PREFIX
+               printk(KERN_ERR LOADER_PREFIX
                       "Cannot alloc page for %u\n", current->tgid);
                goto create_pd_fail;
        }
@@ -160,7 +159,7 @@ static size_t __copy_path(char *src, unsigned long page, unsigned long offset)
 
        /* set handler path */
        if (copy_to_user((void __user *)dest, src, len) != 0) {
-               printk(KERN_ERR PRELOAD_PREFIX
+               printk(KERN_ERR LOADER_PREFIX
                       "Cannot copy string to user!\n");
                return 0;
        }
@@ -171,7 +170,7 @@ static size_t __copy_path(char *src, unsigned long page, unsigned long offset)
 static void __set_ld_mapped(struct pd_t *pd, struct mm_struct *mm)
 {
        struct vm_area_struct *vma;
-       struct dentry *ld = preload_debugfs_get_loader_dentry();
+       struct dentry *ld = ld_get_loader_dentry();
 
        down_read(&mm->mmap_sem);
        if (ld) {
@@ -212,7 +211,7 @@ static int __get_handlers(struct pd_t *pd, struct task_struct *task)
        size_t len;
        int ret = 0;
 
-       handlers = preload_storage_get_handlers();
+       handlers = ls_get_handlers();
        if (handlers == NULL)
                return -EINVAL;
 
@@ -225,7 +224,7 @@ static int __get_handlers(struct pd_t *pd, struct task_struct *task)
 
                hd = kzalloc(sizeof(*hd), GFP_ATOMIC);
                if (hd == NULL) {
-                       printk(KERN_ERR PRELOAD_PREFIX "No atomic mem!\n");
+                       printk(KERN_ERR LOADER_PREFIX "No atomic mem!\n");
                        ret = -ENOMEM;
                        goto get_handlers_out;
                }
@@ -236,7 +235,7 @@ static int __get_handlers(struct pd_t *pd, struct task_struct *task)
                hd->dentry = bin->dentry;
                hd->offset = offset;
                __set_handler_mapped(hd, task->mm);
-               __set_attempts(hd, PRELOAD_MAX_ATTEMPTS);
+               __set_attempts(hd, LOADER_MAX_ATTEMPTS);
                list_add_tail(&hd->list, &pd->handlers);
 
                /* inc handlers path's on page */
@@ -245,25 +244,26 @@ static int __get_handlers(struct pd_t *pd, struct task_struct *task)
 
 get_handlers_out:
        /* TODO Cleanup already created */
-       preload_storage_put_handlers();
+       ls_put_handlers();
 
        return ret;
 }
 
 
 
-enum ps_t preload_pd_get_state(struct hd_t *hd)
+enum ps_t lpd_get_state(struct hd_t *hd)
 {
        if (hd == NULL)
                return 0;
 
        return __get_state(hd);
 }
+EXPORT_SYMBOL_GPL(lpd_get_state);
 
-void preload_pd_set_state(struct hd_t *hd, enum ps_t state)
+void lpd_set_state(struct hd_t *hd, enum ps_t state)
 {
        if (hd == NULL) {
-               printk(PRELOAD_PREFIX "%d: No handler data! Current %d %s\n",
+               printk(LOADER_PREFIX "%d: No handler data! Current %d %s\n",
                       __LINE__, current->tgid, current->comm);
                return;
        }
@@ -271,7 +271,7 @@ void preload_pd_set_state(struct hd_t *hd, enum ps_t state)
        __set_state(hd, state);
 }
 
-unsigned long preload_pd_get_loader_base(struct pd_t *pd)
+unsigned long lpd_get_loader_base(struct pd_t *pd)
 {
        if (pd == NULL)
                return 0;
@@ -279,25 +279,26 @@ unsigned long preload_pd_get_loader_base(struct pd_t *pd)
        return __get_loader_base(pd);
 }
 
-void preload_pd_set_loader_base(struct pd_t *pd, unsigned long vaddr)
+void lpd_set_loader_base(struct pd_t *pd, unsigned long vaddr)
 {
        __set_loader_base(pd, vaddr);
 }
 
-unsigned long preload_pd_get_handlers_base(struct hd_t *hd)
+unsigned long lpd_get_handlers_base(struct hd_t *hd)
 {
        if (hd == NULL)
                return 0;
 
        return __get_handlers_base(hd);
 }
+EXPORT_SYMBOL_GPL(lpd_get_handlers_base);
 
-void preload_pd_set_handlers_base(struct hd_t *hd, unsigned long vaddr)
+void lpd_set_handlers_base(struct hd_t *hd, unsigned long vaddr)
 {
        __set_handlers_base(hd, vaddr);
 }
 
-char __user *preload_pd_get_path(struct pd_t *pd, struct hd_t *hd)
+char __user *lpd_get_path(struct pd_t *pd, struct hd_t *hd)
 {
        unsigned long page = __get_data_page(pd);
        unsigned long offset = __get_offset(hd);
@@ -307,7 +308,7 @@ char __user *preload_pd_get_path(struct pd_t *pd, struct hd_t *hd)
 
 
 
-void *preload_pd_get_handle(struct hd_t *hd)
+void *lpd_get_handle(struct hd_t *hd)
 {
        if (hd == NULL)
                return NULL;
@@ -315,10 +316,10 @@ void *preload_pd_get_handle(struct hd_t *hd)
        return __get_handle(hd);
 }
 
-void preload_pd_set_handle(struct hd_t *hd, void __user *handle)
+void lpd_set_handle(struct hd_t *hd, void __user *handle)
 {
        if (hd == NULL) {
-               printk(PRELOAD_PREFIX "%d: No handler data! Current %d %s\n",
+               printk(LOADER_PREFIX "%d: No handler data! Current %d %s\n",
                       __LINE__, current->tgid, current->comm);
                return;
        }
@@ -326,7 +327,7 @@ void preload_pd_set_handle(struct hd_t *hd, void __user *handle)
        __set_handle(hd, handle);
 }
 
-long preload_pd_get_attempts(struct hd_t *hd)
+long lpd_get_attempts(struct hd_t *hd)
 {
        if (hd == NULL)
                return -EINVAL;
@@ -334,12 +335,12 @@ long preload_pd_get_attempts(struct hd_t *hd)
        return __get_attempts(hd);
 }
 
-void preload_pd_dec_attempts(struct hd_t *hd)
+void lpd_dec_attempts(struct hd_t *hd)
 {
        long attempts;
 
        if (hd == NULL) {
-               printk(PRELOAD_PREFIX "%d: No handler data! Current %d %s\n",
+               printk(LOADER_PREFIX "%d: No handler data! Current %d %s\n",
                       __LINE__, current->tgid, current->comm);
                return;
        }
@@ -349,22 +350,24 @@ void preload_pd_dec_attempts(struct hd_t *hd)
        __set_attempts(hd, attempts);
 }
 
-struct dentry *preload_pd_get_dentry(struct hd_t *hd)
+struct dentry *lpd_get_dentry(struct hd_t *hd)
 {
        return hd->dentry;
 }
 
-struct pd_t *preload_pd_get_parent_pd(struct hd_t *hd)
+struct pd_t *lpd_get_parent_pd(struct hd_t *hd)
 {
        return hd->parent;
 }
+EXPORT_SYMBOL_GPL(lpd_get_parent_pd);
 
-struct pd_t *preload_pd_get(struct sspt_proc *proc)
+struct pd_t *lpd_get(struct sspt_proc *proc)
 {
        return (struct pd_t *)proc->private_data;
 }
+EXPORT_SYMBOL_GPL(lpd_get);
 
-struct hd_t *preload_pd_get_hd(struct pd_t *pd, struct dentry *dentry)
+struct hd_t *lpd_get_hd(struct pd_t *pd, struct dentry *dentry)
 {
        struct hd_t *hd;
 
@@ -375,6 +378,7 @@ struct hd_t *preload_pd_get_hd(struct pd_t *pd, struct dentry *dentry)
 
        return NULL;
 }
+EXPORT_SYMBOL_GPL(lpd_get_hd);
 
 static struct pd_t *do_create_pd(struct task_struct *task)
 {
@@ -399,7 +403,7 @@ free_pd:
        kfree(pd);
 
 create_pd_exit:
-       printk(KERN_ERR PRELOAD_PREFIX "do_pd_create_pd: error=%d\n", ret);
+       printk(KERN_ERR LOADER_PREFIX "do_pd_create_pd: error=%d\n", ret);
        return NULL;
 }
 
@@ -422,7 +426,7 @@ struct sspt_proc_cb pd_cb = {
        .priv_destroy = pd_destroy
 };
 
-int preload_pd_init(void)
+int lpd_init(void)
 {
        int ret;
 
@@ -431,7 +435,7 @@ int preload_pd_init(void)
        return ret;
 }
 
-void preload_pd_uninit(void)
+void lpd_uninit(void)
 {
        sspt_proc_cb_set(NULL);
 
diff --git a/loader/loader_pd.h b/loader/loader_pd.h
new file mode 100644 (file)
index 0000000..73fcb2a
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef __LOADER_PD_H__
+#define __LOADER_PD_H__
+
+#include <loader/loader.h>
+
+struct pd_t;
+struct hd_t;
+struct sspt_proc;
+struct dentry;
+struct list_head;
+
+/* process loader states */
+enum ps_t {
+       NOT_LOADED,
+       LOADING,
+       LOADED,
+       FAILED,
+       ERROR
+};
+
+struct pd_t *lpd_get(struct sspt_proc *proc);
+unsigned long lpd_get_loader_base(struct pd_t *pd);
+void lpd_set_loader_base(struct pd_t *pd, unsigned long vaddr);
+
+struct hd_t *lpd_get_hd(struct pd_t *pd, struct dentry *dentry);
+struct dentry *lpd_get_dentry(struct hd_t *hd);
+struct pd_t *lpd_get_parent_pd(struct hd_t *hd);
+enum ps_t lpd_get_state(struct hd_t *hd);
+void lpd_set_state(struct hd_t *hd, enum ps_t state);
+unsigned long lpd_get_handlers_base(struct hd_t *hd);
+void lpd_set_handlers_base(struct hd_t *hd, unsigned long vaddr);
+void *lpd_get_handle(struct hd_t *hd);
+void lpd_set_handle(struct hd_t *hd, void __user *handle);
+long lpd_get_attempts(struct hd_t *hd);
+void lpd_dec_attempts(struct hd_t *hd);
+
+char __user *lpd_get_path(struct pd_t *pd, struct hd_t *hd);
+
+int lpd_init(void);
+void lpd_uninit(void);
+
+
+#endif /* __LOADER_PD_H__*/
similarity index 54%
rename from preload/preload_storage.c
rename to loader/loader_storage.c
index f2c9ff1..8386cb8 100644 (file)
@@ -4,24 +4,29 @@
 #include <linux/fs.h>
 #include <linux/list.h>
 #include <ks_features/ks_map.h>
-#include "preload.h"
-#include "preload_module.h"
-#include "preload_storage.h"
-#include "preload_handlers.h"
+#include "loader.h"
+#include "loader_module.h"
+#include "loader_storage.h"
 
-static struct bin_info __handlers_info = { NULL, NULL };
 static struct bin_info __linker_info = { NULL, NULL };
 
 static LIST_HEAD(handlers_list);
 
-static inline struct bin_info *__get_handlers_info(void)
-{
-       return &__handlers_info;
-}
 
-static inline bool __check_handlers_info(void)
+static bool __check_dentry_already_exist(struct dentry *dentry)
 {
-       return (__handlers_info.dentry != NULL); /* TODO */
+       struct bin_info_el *bin;
+       bool ret = false;
+
+       list_for_each_entry(bin, &handlers_list, list) {
+               if (bin->dentry == dentry) {
+                       ret = true;
+                       goto out;
+               }
+       }
+
+out:
+       return ret;
 }
 
 static inline int __add_handler(char *path)
@@ -31,10 +36,21 @@ static inline int __add_handler(char *path)
        struct bin_info_el *bin;
        int ret = 0;
 
+       dentry = get_dentry(path);
+       if (!dentry) {
+               ret = -ENOENT;
+               goto add_handler_out;
+       }
+
+       if (__check_dentry_already_exist(dentry)) {
+               ret = 1;
+               goto add_handler_out;
+       }
+
        bin = kmalloc(sizeof(*bin), GFP_KERNEL);
        if (bin == NULL) {
                ret = -ENOMEM;
-               goto add_handler_fail;
+               goto add_handler_fail_release_dentry;
        }
 
        bin->path = kmalloc(len + 1, GFP_KERNEL);
@@ -43,12 +59,6 @@ static inline int __add_handler(char *path)
                goto add_handler_fail_free_bin;
        }
 
-       dentry = get_dentry(path);
-       if (!dentry) {
-               ret = -ENOENT;
-               goto add_handler_fail_free_path;
-       }
-
        INIT_LIST_HEAD(&bin->list);
        strncpy(bin->path, path, len);
        bin->path[len] = '\0';
@@ -57,13 +67,13 @@ static inline int __add_handler(char *path)
 
        return ret;
 
-add_handler_fail_free_path:
-       kfree(bin->path);
-
 add_handler_fail_free_bin:
        kfree(bin);
 
-add_handler_fail:
+add_handler_fail_release_dentry:
+       put_dentry(dentry);
+
+add_handler_out:
        return ret;
 }
 
@@ -83,47 +93,6 @@ static inline void __remove_handlers(void)
                __remove_handler(bin);
 }
 
-static inline int __init_handlers_info(char *path)
-{
-       struct dentry *dentry;
-       size_t len = strnlen(path, PATH_MAX);
-       int ret = 0;
-
-       __handlers_info.path = kmalloc(len + 1, GFP_KERNEL);
-       if (__handlers_info.path == NULL) {
-               ret = -ENOMEM;
-               goto init_handlers_fail;
-       }
-
-       dentry = get_dentry(path);
-       if (!dentry) {
-               ret = -ENOENT;
-               goto init_handlers_fail_free;
-       }
-
-       strncpy(__handlers_info.path, path, len);
-       __handlers_info.path[len] = '\0';
-       __handlers_info.dentry = dentry;
-
-       return ret;
-
-init_handlers_fail_free:
-       kfree(__handlers_info.path);
-
-init_handlers_fail:
-       return ret;
-}
-
-static inline void __drop_handlers_info(void)
-{
-       kfree(__handlers_info.path);
-       __handlers_info.path = NULL;
-
-       if (__handlers_info.dentry)
-               put_dentry(__handlers_info.dentry);
-       __handlers_info.dentry = NULL;
-}
-
 static inline struct bin_info *__get_linker_info(void)
 {
        return &__linker_info;
@@ -180,65 +149,36 @@ static inline void __drop_linker_info(void)
 
 
 
-int preload_storage_set_handlers_info(char *path)
+int ls_add_handler(char *path)
 {
        int ret;
 
-       ret = __init_handlers_info(path);
-       if (ret != 0)
-               return ret;
-
+       /* If ret is positive - handler was not added, because it is
+        * already exists */
        ret = __add_handler(path);
-       if (ret != 0)
+       if (ret < 0)
                return ret;
 
-       ph_set_handler_dentry(__handlers_info.dentry);
-
-       return ret;
-}
-
-int preload_storage_add_handler(char *path)
-{
-       int ret;
-
-       ret = __add_handler(path);
-       if (ret != 0)
-               return ret;
-
-       return ret;
-}
-
-struct bin_info *preload_storage_get_handlers_info(void)
-{
-       struct bin_info *info = __get_handlers_info();
-
-       if (__check_handlers_info())
-               return info;
-
-       return NULL;
+       return 0;
 }
 
-struct list_head *preload_storage_get_handlers(void)
+struct list_head *ls_get_handlers(void)
 {
        /* TODO counter, syncs */
        return &handlers_list;
 }
 
-void preload_storage_put_handlers_info(struct bin_info *info)
-{
-}
-
-void preload_storage_put_handlers(void)
+void ls_put_handlers(void)
 {
        /* TODO dec counter, release sync */
 }
 
-int preload_storage_set_linker_info(char *path)
+int ls_set_linker_info(char *path)
 {
        return __init_linker_info(path);
 }
 
-struct bin_info *preload_storage_get_linker_info(void)
+struct bin_info *ls_get_linker_info(void)
 {
        struct bin_info *info = __get_linker_info();
 
@@ -248,18 +188,17 @@ struct bin_info *preload_storage_get_linker_info(void)
        return NULL;
 }
 
-void preload_storage_put_linker_info(struct bin_info *info)
+void ls_put_linker_info(struct bin_info *info)
 {
 }
 
-int preload_storage_init(void)
+int ls_init(void)
 {
        return 0;
 }
 
-void preload_storage_exit(void)
+void ls_exit(void)
 {
-       __drop_handlers_info();
        __drop_linker_info();
        __remove_handlers();
 }
diff --git a/loader/loader_storage.h b/loader/loader_storage.h
new file mode 100644 (file)
index 0000000..4f84a9c
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __LOADER_STORAGE_H__
+#define __LOADER_STORAGE_H__
+
+struct list_head;
+struct dentry;
+
+struct bin_info {
+       char *path;
+       /* ghot */
+       struct dentry *dentry;
+};
+
+struct bin_info_el {
+       struct list_head list;
+       char *path;
+       /* ghot */
+       struct dentry *dentry;
+};
+
+
+
+int ls_add_handler(char *path);
+struct list_head *ls_get_handlers(void);
+void ls_put_handlers(void);
+
+int ls_set_linker_info(char *path);
+struct bin_info *ls_get_linker_info(void);
+void ls_put_linker_info(struct bin_info *info);
+
+int ls_init(void);
+void ls_exit(void);
+
+#endif /* __LOADER_HANDLERS_H__ */
index 43d4f59..b2a6709 100755 (executable)
@@ -57,6 +57,7 @@ install -m 666 energy/swap_energy.ko -t %{buildroot}/opt/swap/sdk
 install -m 666 parser/swap_message_parser.ko -t %{buildroot}/opt/swap/sdk
 install -m 666 retprobe/swap_retprobe.ko -t %{buildroot}/opt/swap/sdk
 install -m 666 webprobe/swap_webprobe.ko -t %{buildroot}/opt/swap/sdk
+install -m 666 loader/swap_loader.ko -t %{buildroot}/opt/swap/sdk
 install -m 666 preload/swap_preload.ko -t %{buildroot}/opt/swap/sdk
 install -m 666 fbiprobe/swap_fbiprobe.ko -t %{buildroot}/opt/swap/sdk
 install -m 666 wsp/swap_wsp.ko -t %{buildroot}/opt/swap/sdk
@@ -84,6 +85,7 @@ cp LICENSE.GPL-2.0+ %{buildroot}/usr/share/license/%{name}
 /opt/swap/sdk/swap_message_parser.ko
 /opt/swap/sdk/swap_retprobe.ko
 /opt/swap/sdk/swap_webprobe.ko
+/opt/swap/sdk/swap_loader.ko
 /opt/swap/sdk/swap_preload.ko
 /opt/swap/sdk/swap_fbiprobe.ko
 /opt/swap/sdk/swap_wsp.ko
index e118bce..425a43d 100644 (file)
@@ -2,10 +2,7 @@ EXTRA_CFLAGS := $(extra_cflags)
 
 obj-m := swap_preload.o
 swap_preload-y := preload_module.o \
-                  preload_handlers.o \
+                  preload_control.o \
                   preload_debugfs.o \
-                  preload_storage.o \
                   preload_probe.o \
-                  preload_control.o \
-                  preload_threads.o \
-                  preload_pd.o
+                  preload_threads.o
index 841ab28..f895f81 100644 (file)
@@ -6,9 +6,9 @@
 #include <us_manager/sspt/sspt_ip.h>
 
 #include "preload.h"
+#include "preload_module.h"
 #include "preload_control.h"
 #include "preload_probe.h"
-#include "preload_module.h"
 
 struct bin_desc {
        struct list_head list;
@@ -202,7 +202,7 @@ out:
 
 
 /* Called only form handlers. If we're there, then it is instrumented. */
-enum preload_call_type preload_control_call_type_always_inst(void *caller)
+enum preload_call_type pc_call_type_always_inst(void *caller)
 {
        if (__is_instrumented(caller))
                return INTERNAL_CALL;
@@ -211,7 +211,7 @@ enum preload_call_type preload_control_call_type_always_inst(void *caller)
 
 }
 
-enum preload_call_type preload_control_call_type(struct sspt_ip *ip, void *caller)
+enum preload_call_type pc_call_type(struct sspt_ip *ip, void *caller)
 {
        if (__is_instrumented(caller))
                return INTERNAL_CALL;
@@ -222,7 +222,7 @@ enum preload_call_type preload_control_call_type(struct sspt_ip *ip, void *calle
        return NOT_INSTRUMENTED;
 }
 
-int preload_control_add_instrumented_binary(char *filename)
+int pc_add_instrumented_binary(char *filename)
 {
        struct dentry *dentry = get_dentry(filename);
        int res = 0;
@@ -237,14 +237,14 @@ int preload_control_add_instrumented_binary(char *filename)
        return res > 0 ? 0 : res;
 }
 
-int preload_control_clean_instrumented_bins(void)
+int pc_clean_instrumented_bins(void)
 {
        __free_binaries(&target);
 
        return 0;
 }
 
-int preload_control_add_ignored_binary(char *filename)
+int pc_add_ignored_binary(char *filename)
 {
        struct dentry *dentry = get_dentry(filename);
        int res = 0;
@@ -259,34 +259,34 @@ int preload_control_add_ignored_binary(char *filename)
        return res > 0 ? 0 : res;
 }
 
-int preload_control_clean_ignored_bins(void)
+int pc_clean_ignored_bins(void)
 {
        __free_binaries(&ignored);
 
        return 0;
 }
 
-unsigned int preload_control_get_target_names(char ***filenames_p)
+unsigned int pc_get_target_names(char ***filenames_p)
 {
        return __get_names(&target, filenames_p);
 }
 
-void preload_control_release_target_names(char ***filenames_p)
+void pc_release_target_names(char ***filenames_p)
 {
        kfree(*filenames_p);
 }
 
-unsigned int preload_control_get_ignored_names(char ***filenames_p)
+unsigned int pc_get_ignored_names(char ***filenames_p)
 {
        return __get_names(&ignored, filenames_p);
 }
 
-void preload_control_release_ignored_names(char ***filenames_p)
+void pc_release_ignored_names(char ***filenames_p)
 {
        kfree(*filenames_p);
 }
 
-bool preload_control_check_dentry_is_ignored(struct dentry *dentry)
+bool pc_check_dentry_is_ignored(struct dentry *dentry)
 {
        struct bin_desc *p;
        bool ret = false;
@@ -308,12 +308,12 @@ bool preload_control_check_dentry_is_ignored(struct dentry *dentry)
        return ret;
 }
 
-int preload_control_init(void)
+int pc_init(void)
 {
        return 0;
 }
 
-void preload_control_exit(void)
+void pc_exit(void)
 {
        __free_binaries(&target);
        __free_binaries(&ignored);
index 419d61e..4e6f1d0 100644 (file)
@@ -9,22 +9,22 @@ enum preload_call_type {
        INTERNAL_CALL
 };
 
-int preload_control_init(void);
-void preload_control_exit(void);
+int pc_init(void);
+void pc_exit(void);
 
-enum preload_call_type preload_control_call_type_always_inst(void *caller);
-enum preload_call_type preload_control_call_type(struct sspt_ip *ip, void *caller);
-int preload_control_add_instrumented_binary(char *filename);
-int preload_control_clean_instrumented_bins(void);
-int preload_control_add_ignored_binary(char *filename);
-int preload_control_clean_ignored_bins(void);
+enum preload_call_type pc_call_type_always_inst(void *caller);
+enum preload_call_type pc_call_type(struct sspt_ip *ip, void *caller);
+int pc_add_instrumented_binary(char *filename);
+int pc_clean_instrumented_bins(void);
+int pc_add_ignored_binary(char *filename);
+int pc_clean_ignored_bins(void);
 
-unsigned int preload_control_get_target_names(char ***filenames_p);
-void preload_control_release_target_names(char ***filenames_p);
+unsigned int pc_get_target_names(char ***filenames_p);
+void pc_release_target_names(char ***filenames_p);
 
-unsigned int preload_control_get_ignored_names(char ***filenames_p);
-void preload_control_release_ignored_names(char ***filenames_p);
+unsigned int pc_get_ignored_names(char ***filenames_p);
+void pc_release_ignored_names(char ***filenames_p);
 
-bool preload_control_check_dentry_is_ignored(struct dentry *dentry);
+bool pc_check_dentry_is_ignored(struct dentry *dentry);
 
-#endif /* __PRELOAD_CONTROL_H__ */
+#endif /* __PRELOAD_HANDLERS_CONTROL_H__ */
index 9896aef..b525b05 100644 (file)
@@ -9,36 +9,20 @@
 #include <asm/uaccess.h>
 #include <master/swap_debugfs.h>
 #include "preload.h"
-#include "preload_debugfs.h"
 #include "preload_module.h"
+#include "preload_debugfs.h"
 #include "preload_control.h"
-#include "preload_storage.h"
 
 static const char PRELOAD_FOLDER[] = "preload";
-static const char PRELOAD_LOADER[] = "loader";
-static const char PRELOAD_LOADER_OFFSET[] = "loader_offset";
-static const char PRELOAD_LOADER_PATH[] = "loader_path";
+static const char PRELOAD_HANDLER[] = "handler";
 static const char PRELOAD_TARGET[] = "target_binaries";
 static const char PRELOAD_IGNORED[] = "ignored_binaries";
 static const char PRELOAD_BINARIES_LIST[] = "bins_list";
 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_LINKER_DATA[] = "linker";
-static const char PRELOAD_LINKER_PATH[] = "linker_path";
-static const char PRELOAD_LINKER_R_DEBUG_OFFSET[] = "r_debug_offset";
 
-struct loader_info {
-       char *path;
-       unsigned long offset;
-       struct dentry *dentry;
-};
 
 static struct dentry *preload_root;
-static struct loader_info __loader_info;
-
-
 static struct dentry *target_list = NULL;
 static struct dentry *target_add = NULL;
 static struct dentry *target_remove = NULL;
@@ -46,128 +30,6 @@ static struct dentry *ignored_list = NULL;
 static struct dentry *ignored_add = NULL;
 static struct dentry *ignored_remove = NULL;
 
-static unsigned long r_debug_offset = 0;
-static DEFINE_SPINLOCK(__dentry_lock);
-
-static inline void dentry_lock(void)
-{
-       spin_lock(&__dentry_lock);
-}
-
-static inline void dentry_unlock(void)
-{
-       spin_unlock(&__dentry_lock);
-}
-
-
-static void set_loader_file(char *path)
-{
-       __loader_info.path = path;
-       dentry_lock();
-       __loader_info.dentry = get_dentry(__loader_info.path);
-       dentry_unlock();
-}
-
-struct dentry *preload_debugfs_get_loader_dentry(void)
-{
-       struct dentry *dentry;
-
-       dentry_lock();
-       dentry = __loader_info.dentry;
-       dentry_unlock();
-
-       return dentry;
-}
-
-unsigned long preload_debugfs_get_loader_offset(void)
-{
-       /* TODO Think about sync */
-       return __loader_info.offset;
-}
-
-static void clean_loader_info(void)
-{
-       if (__loader_info.path != NULL)
-               kfree(__loader_info.path);
-       __loader_info.path = NULL;
-
-       dentry_lock();
-       if (__loader_info.dentry != NULL)
-               put_dentry(__loader_info.dentry);
-
-       __loader_info.dentry = NULL;
-       __loader_info.offset = 0;
-
-       dentry_unlock();
-}
-
-struct dentry *debugfs_create_ptr(const char *name, mode_t mode,
-                                 struct dentry *parent,
-                                 unsigned long *value)
-{
-       struct dentry *dentry;
-
-#if BITS_PER_LONG == 32
-       dentry = debugfs_create_x32(name, mode, parent, (u32 *)value);
-#elif BITS_PER_LONG == 64
-       dentry = debugfs_create_x64(name, mode, parent, (u64 *)value);
-#else
-#error Unsupported BITS_PER_LONG value
-#endif
-
-       return dentry;
-}
-
-
-/* ===========================================================================
- * =                              LOADER PATH                                =
- * ===========================================================================
- */
-
-static ssize_t loader_path_write(struct file *file, const char __user *buf,
-                                size_t len, loff_t *ppos)
-{
-       ssize_t ret;
-       char *path;
-
-       if (preload_module_is_running())
-               return -EBUSY;
-
-       clean_loader_info();
-
-       path = kmalloc(len, GFP_KERNEL);
-       if (path == NULL) {
-               return -ENOMEM;
-       }
-
-       if (copy_from_user(path, buf, len)) {
-               ret = -EINVAL;
-               goto err;
-       }
-
-       path[len - 1] = '\0';
-       set_loader_file(path);
-
-       ret = preload_control_add_ignored_binary(path);
-       if (ret < 0) {
-               printk(PRELOAD_PREFIX "Cannot add loader %s to ignored list\n", path);
-               goto err;
-       }
-
-       ret = len;
-
-       return ret;
-err:
-       kfree(path);
-       return ret;
-}
-
-
-static const struct file_operations loader_path_file_ops = {
-       .owner = THIS_MODULE,
-       .write = loader_path_write,
-};
-
 
 /* ===========================================================================
  * =                                BIN PATH                                 =
@@ -194,9 +56,9 @@ static ssize_t bin_add_write(struct file *file, const char __user *buf,
        path[len - 1] = '\0';
 
        if (file->f_path.dentry == target_add)
-               ret = preload_control_add_instrumented_binary(path);
+               ret = pc_add_instrumented_binary(path);
        else if (file->f_path.dentry == ignored_add)
-               ret = preload_control_add_ignored_binary(path);
+               ret = pc_add_ignored_binary(path);
        else {
                /* Should never occur */
                printk(PRELOAD_PREFIX "%s() called for invalid file %s!\n", __func__,
@@ -226,9 +88,9 @@ static ssize_t bin_remove_write(struct file *file, const char __user *buf,
        ssize_t ret;
 
        if (file->f_path.dentry == target_remove)
-               ret = preload_control_clean_instrumented_bins();
+               ret = pc_clean_instrumented_bins();
        else if (file->f_path.dentry == ignored_remove)
-               ret = preload_control_clean_ignored_bins();
+               ret = pc_clean_ignored_bins();
        else {
                /* Should never occur */
                printk(PRELOAD_PREFIX "%s() called for invalid file %s!\n", __func__,
@@ -260,9 +122,9 @@ static ssize_t bin_list_read(struct file *file, char __user *usr_buf,
        char *ptr = NULL;
 
        if (file->f_path.dentry == target_list) {
-               files_cnt = preload_control_get_target_names(&filenames);
+               files_cnt = pc_get_target_names(&filenames);
        } else if (file->f_path.dentry == ignored_list) {
-               files_cnt = preload_control_get_ignored_names(&filenames);
+               files_cnt = pc_get_ignored_names(&filenames);
        } else {
                /* Should never occur */
                printk(PRELOAD_PREFIX "%s() called for invalid file %s!\n", __func__,
@@ -302,9 +164,9 @@ static ssize_t bin_list_read(struct file *file, char __user *usr_buf,
 
 bin_list_read_fail:
        if (file->f_path.dentry == target_list) {
-               preload_control_release_target_names(&filenames);
+               pc_release_target_names(&filenames);
        } else if (file->f_path.dentry == ignored_list)  {
-               preload_control_release_ignored_names(&filenames);
+               pc_release_ignored_names(&filenames);
        } else {
                /* Should never occur */
                printk(PRELOAD_PREFIX "%s() called for invalid file %s!\n", __func__,
@@ -331,66 +193,14 @@ static const struct file_operations bin_remove_file_ops = {
        .write = bin_remove_write,
 };
 
-
 /* ===========================================================================
- * =                            LINKER PATH                                  =
+ * =                              HANDLER                                    =
  * ===========================================================================
  */
 
 
-static ssize_t linker_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 linker_path_write_out;
-       }
-
-       if (copy_from_user(path, buf, len)) {
-               ret = -EINVAL;
-               goto linker_path_write_out;
-       }
-
-       path[len - 1] = '\0';
-
-       if (preload_storage_set_linker_info(path) != 0) {
-               printk(PRELOAD_PREFIX "Cannot set linker path %s\n", path);
-               ret = -EINVAL;
-               goto linker_path_write_out;
-       }
-
-       ret = preload_control_add_ignored_binary(path);
-       if (ret < 0) {
-               printk(PRELOAD_PREFIX "Cannot add linker %s to ignored list\n", path);
-               goto linker_path_write_out;
-       }
-
-       ret = len;
-
-linker_path_write_out:
-       kfree(path);
-
-       return ret;
-}
-
-static const struct file_operations linker_path_file_ops = {
-       .owner = THIS_MODULE,
-       .write = linker_path_write,
-};
-
-
-/* ===========================================================================
- * =                           HANDLERS PATH                                 =
- * ===========================================================================
- */
-
-
-static ssize_t handlers_path_write(struct file *file, const char __user *buf,
-                                  size_t len, loff_t *ppos)
+static ssize_t handler_write(struct file *file, const char __user *buf,
+                            size_t len, loff_t *ppos)
 {
        ssize_t ret;
        char *path;
@@ -408,7 +218,7 @@ static ssize_t handlers_path_write(struct file *file, const char __user *buf,
 
        path[len - 1] = '\0';
 
-       if (preload_storage_set_handlers_info(path) != 0) {
+       if (pm_set_handler(path) != 0) {
                printk(PRELOAD_PREFIX "Cannot set handler path %s\n", path);
                ret = -EINVAL;
                goto handlers_path_write_out;
@@ -422,24 +232,17 @@ handlers_path_write_out:
        return ret;
 }
 
-static const struct file_operations handlers_path_file_ops = {
+static const struct file_operations handler_file_ops = {
        .owner = THIS_MODULE,
-       .write = handlers_path_write,
+       .write = handler_write,
 };
 
 
 
 
-unsigned long preload_debugfs_r_debug_offset(void)
+int pd_init(void)
 {
-       return r_debug_offset;
-}
-
-int preload_debugfs_init(void)
-{
-       struct dentry *swap_dentry, *root, *loader, *open_p, *lib_path,
-                 *target_path, *ignored_path, *linker_dir, *linker_path,
-                 *linker_offset, *handlers_path;
+       struct dentry *swap_dentry, *root, *target_path, *ignored_path, *handler;
        int ret;
 
        ret = -ENODEV;
@@ -458,26 +261,6 @@ int preload_debugfs_init(void)
 
        preload_root = root;
 
-       loader = debugfs_create_dir(PRELOAD_LOADER, root);
-       if (IS_ERR_OR_NULL(root)) {
-               ret = -ENOMEM;
-               goto remove;
-       }
-
-       open_p = debugfs_create_ptr(PRELOAD_LOADER_OFFSET, PRELOAD_DEFAULT_PERMS,
-                                   loader, &__loader_info.offset);
-       if (IS_ERR_OR_NULL(open_p)) {
-               ret = -ENOMEM;
-               goto remove;
-       }
-
-       lib_path = debugfs_create_file(PRELOAD_LOADER_PATH, PRELOAD_DEFAULT_PERMS,
-                                      loader, NULL, &loader_path_file_ops);
-       if (IS_ERR_OR_NULL(lib_path)) {
-               ret = -ENOMEM;
-               goto remove;
-       }
-
        target_path = debugfs_create_dir(PRELOAD_TARGET, root);
        if (IS_ERR_OR_NULL(target_path)) {
                ret = -ENOMEM;
@@ -538,32 +321,9 @@ int preload_debugfs_init(void)
                goto remove;
        }
 
-       linker_dir = debugfs_create_dir(PRELOAD_LINKER_DATA, root);
-       if (IS_ERR_OR_NULL(linker_dir)) {
-               ret = -ENOMEM;
-               goto remove;
-       }
-
-       linker_path = debugfs_create_file(PRELOAD_LINKER_PATH,
-                                         PRELOAD_DEFAULT_PERMS, linker_dir, NULL,
-                                         &linker_path_file_ops);
-       if (IS_ERR_OR_NULL(linker_path)) {
-               ret = -ENOMEM;
-               goto remove;
-       }
-
-       linker_offset = debugfs_create_ptr(PRELOAD_LINKER_R_DEBUG_OFFSET,
-                                          PRELOAD_DEFAULT_PERMS, linker_dir,
-                                          &r_debug_offset);
-       if (IS_ERR_OR_NULL(linker_offset)) {
-               ret = -ENOMEM;
-               goto remove;
-       }
-
-       handlers_path = debugfs_create_file(PRELOAD_HANDLERS_PATH,
-                                           PRELOAD_DEFAULT_PERMS, root, NULL,
-                                           &handlers_path_file_ops);
-       if (IS_ERR_OR_NULL(handlers_path)) {
+       handler = debugfs_create_file(PRELOAD_HANDLER, PRELOAD_DEFAULT_PERMS,
+                                 preload_root, NULL, &handler_file_ops);
+       if (IS_ERR_OR_NULL(handler)) {
                ret = -ENOMEM;
                goto remove;
        }
@@ -580,7 +340,7 @@ fail:
        return ret;
 }
 
-void preload_debugfs_exit(void)
+void pd_exit(void)
 {
        if (preload_root)
                debugfs_remove_recursive(preload_root);
@@ -591,7 +351,4 @@ void preload_debugfs_exit(void)
        ignored_add = NULL;
        ignored_remove = NULL;
        preload_root = NULL;
-
-       preload_module_set_not_ready();
-       clean_loader_info();
 }
index d2c457b..bae931d 100644 (file)
@@ -1,16 +1,9 @@
-#ifndef __PRELOAD_DEBUGFS_H__
-#define __PRELOAD_DEBUGFS_H__
+#ifndef __PRELOAD_HANDLERS_DEBUGFS_H__
+#define __PRELOAD_HANDLERS_DEBUGFS_H__
 
 struct dentry;
 
-int preload_debugfs_init(void);
-void preload_debugfs_exit(void);
+int pd_init(void);
+void pd_exit(void);
 
-struct dentry *preload_debugfs_get_loader_dentry(void);
-unsigned long preload_debugfs_get_loader_offset(void);
-
-struct dentry *preload_debugfs_create_new_thread(unsigned long tid);
-
-unsigned long preload_debugfs_r_debug_offset(void);
-
-#endif /* __PRELOAD_DEBUGFS_H__ */
+#endif /* __PRELOAD_HANDLERS_DEBUGFS_H__ */
diff --git a/preload/preload_handlers.c b/preload/preload_handlers.c
deleted file mode 100644 (file)
index ec5fa84..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-#include <linux/slab.h>
-#include <kprobe/swap_kprobes_deps.h>
-#include <writer/kernel_operations.h>
-#include <writer/swap_msg.h>
-#include <us_manager/sspt/sspt_ip.h>
-#include <us_manager/sspt/sspt_page.h>
-#include <us_manager/sspt/sspt_file.h>
-#include "preload.h"
-#include "preload_pd.h"
-#include "preload_control.h"
-#include "preload_threads.h"
-#include "preload_module.h"
-
-#define page_to_proc(page) ((page)->file->proc)
-#define ip_to_proc(ip) page_to_proc((ip)->page)
-#define urp_to_ip(rp) container_of(rp, struct sspt_ip, retprobe)
-
-enum {
-       /* task preload flags */
-       HANDLER_RUNNING = 0x1
-};
-
-static struct dentry *handler_dentry = NULL;
-
-
-static inline struct pd_t *__get_process_data(struct uretprobe *rp)
-{
-       struct sspt_ip *ip = urp_to_ip(rp);
-       struct sspt_proc *proc = ip_to_proc(ip);
-
-       return preload_pd_get(proc);
-}
-
-static inline struct vm_area_struct *__get_vma_by_addr(struct task_struct *task,
-                                                      unsigned long caddr)
-{
-       struct vm_area_struct *vma = NULL;
-
-       if ((task == NULL) || (task->mm == NULL))
-               return NULL;
-       vma = find_vma_intersection(task->mm, caddr, caddr + 1);
-
-       return vma;
-}
-
-static inline bool __is_probe_non_block(struct sspt_ip *ip)
-{
-       if (ip->desc->info.pl_i.flags & SWAP_PRELOAD_NON_BLOCK_PROBE)
-               return true;
-
-       return false;
-}
-
-static inline bool __inverted(struct sspt_ip *ip)
-{
-       unsigned long flags = ip->desc->info.pl_i.flags;
-
-       if (flags & SWAP_PRELOAD_INVERTED_PROBE)
-               return true;
-
-       return false;
-}
-
-static inline bool __check_flag_and_call_type(struct sspt_ip *ip,
-                                             enum preload_call_type ct)
-{
-       bool inverted = __inverted(ip);
-
-       if (ct != NOT_INSTRUMENTED || inverted)
-               return true;
-
-       return false;
-}
-
-static inline bool __is_handlers_call(struct vm_area_struct *caller,
-                                     struct pd_t *pd)
-{
-       struct hd_t *hd;
-
-       if (caller == NULL || caller->vm_file == NULL ||
-           caller->vm_file->f_path.dentry == NULL) {
-               return false;
-       }
-
-       hd = preload_pd_get_hd(pd, caller->vm_file->f_path.dentry);
-       if (hd != NULL)
-               return true;
-
-       return false;
-}
-
-static inline bool __should_drop(struct sspt_ip *ip, enum preload_call_type ct)
-{
-       if (ct == NOT_INSTRUMENTED)
-               return true;
-
-       return false;
-}
-
-static inline int __msg_sanitization(char *user_msg, size_t len,
-                                    char *call_type_p, char *caller_p)
-{
-       if ((call_type_p < user_msg) || (call_type_p > user_msg + len) ||
-           (caller_p < user_msg) || (caller_p > user_msg + len))
-               return -EINVAL;
-
-       return 0;
-}
-
-
-
-
-static unsigned long __do_preload_entry(struct uretprobe_instance *ri,
-                                       struct pt_regs *regs,
-                                       struct hd_t *hd)
-{
-       struct sspt_ip *ip = container_of(ri->rp, struct sspt_ip, retprobe);
-       unsigned long offset = ip->desc->info.pl_i.handler;
-       unsigned long vaddr = 0;
-       unsigned long base;
-       unsigned long disable_addr;
-       unsigned long caddr;
-       struct vm_area_struct *cvma;
-       enum preload_call_type ct;
-
-       base = preload_pd_get_handlers_base(hd);
-       if (base == 0)
-               return 0;       /* handlers isn't mapped */
-
-       /* jump to preloaded handler */
-       vaddr = base + offset;
-       if (vaddr) {
-               caddr = get_regs_ret_func(regs);
-               cvma = __get_vma_by_addr(current, caddr);
-               ct = preload_control_call_type(ip, (void *)caddr);
-               disable_addr = __is_probe_non_block(ip) ? ip->orig_addr : 0;
-
-               /* jump only if caller is instumented and it is not a system lib -
-                * this leads to some errors */
-               if (cvma != NULL && cvma->vm_file != NULL &&
-                       cvma->vm_file->f_dentry != NULL) {
-
-                       struct dentry *dentry = cvma->vm_file->f_dentry;
-                       struct pd_t *pd = preload_pd_get_parent_pd(hd);
-
-                       if (!preload_control_check_dentry_is_ignored(dentry) &&
-                           __check_flag_and_call_type(ip, ct) &&
-                           !__is_handlers_call(cvma, pd)) {
-
-                               bool drop = __should_drop(ip, ct);
-                               if (preload_threads_set_data(current, caddr,
-                                                            ct, disable_addr,
-                                                            drop) != 0)
-                                       printk(PRELOAD_PREFIX "Error! Failed "
-                                              "to set caller 0x%lx for "
-                                              "%d/%d\n", caddr,
-                                              current->tgid,
-                                              current->pid);
-                               /* args are not changed */
-                               preload_module_prepare_ujump(ri, regs, vaddr);
-                               if (disable_addr == 0)
-                                       set_preload_flags(current,
-                                                         HANDLER_RUNNING);
-                       }
-               }
-       }
-
-       return vaddr;
-}
-
-static int preload_us_entry(struct uretprobe_instance *ri, struct pt_regs *regs)
-{
-       struct pd_t *pd = __get_process_data(ri->rp);
-       struct hd_t *hd;
-       unsigned long old_pc = swap_get_instr_ptr(regs);
-       unsigned long flags = get_preload_flags(current);
-       struct sspt_ip *ip = container_of(ri->rp, struct sspt_ip, retprobe);
-       unsigned long vaddr = 0;
-
-       if (handler_dentry == NULL)
-               goto out_set_orig;
-
-       if ((flags & HANDLER_RUNNING) ||
-           preload_threads_check_disabled_probe(current, ip->orig_addr))
-               goto out_set_orig;
-
-       hd = preload_pd_get_hd(pd, handler_dentry);
-       if (hd == NULL)
-               goto out_set_orig;
-
-       if ((flags & HANDLER_RUNNING) ||
-               preload_threads_check_disabled_probe(current, ip->orig_addr))
-               goto out_set_orig;
-
-       if (preload_pd_get_state(hd) == NOT_LOADED ||
-           preload_pd_get_state(hd) == FAILED)
-               vaddr = preload_not_loaded_entry(ri, regs, pd, hd);
-       else if (preload_pd_get_state(hd) == LOADED)
-               vaddr =__do_preload_entry(ri, regs, hd);
-
-out_set_orig:
-       preload_set_priv_origin(ri, vaddr);
-
-       /* PC change check */
-       return old_pc != swap_get_instr_ptr(regs);
-}
-
-static void __do_preload_ret(struct uretprobe_instance *ri, struct hd_t *hd)
-{
-       struct sspt_ip *ip = container_of(ri->rp, struct sspt_ip, retprobe);
-       unsigned long flags = get_preload_flags(current);
-       unsigned long offset = ip->desc->info.pl_i.handler;
-       unsigned long vaddr = 0;
-
-       if ((flags & HANDLER_RUNNING) ||
-           preload_threads_check_disabled_probe(current, ip->orig_addr)) {
-               bool non_blk_probe = __is_probe_non_block(ip);
-
-               /* drop the flag if the handler has completed */
-               vaddr = preload_pd_get_handlers_base(hd) + offset;
-               if (vaddr && (preload_get_priv_origin(ri) == vaddr)) {
-                       if (preload_threads_put_data(current) != 0)
-                               printk(PRELOAD_PREFIX "Error! Failed to put "
-                                      "caller slot for %d/%d\n", current->tgid,
-                                      current->pid);
-                       if (!non_blk_probe) {
-                               flags &= ~HANDLER_RUNNING;
-                               set_preload_flags(current, flags);
-                       }
-               }
-       }
-}
-
-static int preload_us_ret(struct uretprobe_instance *ri, struct pt_regs *regs)
-{
-       struct pd_t *pd = __get_process_data(ri->rp);
-       struct hd_t *hd;
-
-       if (handler_dentry == NULL)
-               return 0;
-
-       hd = preload_pd_get_hd(pd, handler_dentry);
-       if (hd == NULL)
-               return 0;
-
-       switch (preload_pd_get_state(hd)) {
-       case NOT_LOADED:
-               /* loader has not yet been mapped... just ignore */
-               break;
-       case LOADING:
-               preload_loading_ret(ri, regs, pd, hd);
-               break;
-       case LOADED:
-               __do_preload_ret(ri, hd);
-               break;
-       case FAILED:
-               preload_failed_ret(ri, regs, pd, hd);
-               break;
-       case ERROR:
-       default:
-               break;
-       }
-
-       return 0;
-}
-
-
-
-
-
-static void __write_data_to_msg(char *msg, size_t len,
-                               unsigned long call_type_off,
-                               unsigned long caller_off,
-                               unsigned long caller_addr)
-{
-       unsigned char call_type = 0;
-       unsigned long caller = 0;
-       int ret;
-
-       if (caller_addr != 0) {
-               caller = caller_addr;
-               call_type =
-                   preload_control_call_type_always_inst((void *)caller);
-       } else {
-               ret = preload_threads_get_caller(current, &caller);
-               if (ret != 0) {
-                       caller = 0xbadbeef;
-                       printk(PRELOAD_PREFIX "Error! Cannot get caller address"
-                              " for %d/%d\n", current->tgid, current->pid);
-               }
-
-               ret = preload_threads_get_call_type(current, &call_type);
-               if (ret != 0) {
-                       call_type = 0xff;
-                       printk(PRELOAD_PREFIX "Error! Cannot get call type for "
-                              "%d/%d\n", current->tgid, current->pid);
-               }
-       }
-
-       /* Using the same types as in the library. */
-       *(uint32_t *)(msg + call_type_off) = (uint32_t)call_type;
-       *(uintptr_t *)(msg + caller_off) = (uintptr_t)caller;
-}
-
-static int write_msg_handler(struct uprobe *p, struct pt_regs *regs)
-{
-       char *user_buf;
-       char *buf;
-       char *caller_p;
-       char *call_type_p;
-       size_t len;
-       unsigned long caller_offset;
-       unsigned long call_type_offset;
-       unsigned long caller_addr;
-       int ret;
-
-       /* FIXME: swap_get_uarg uses get_user(), it might sleep */
-       user_buf = (char *)swap_get_uarg(regs, 0);
-       len = swap_get_uarg(regs, 1);
-       call_type_p = (char *)swap_get_uarg(regs, 2);
-       caller_p = (char *)swap_get_uarg(regs, 3);
-       caller_addr = swap_get_uarg(regs, 4);
-
-       ret = __msg_sanitization(user_buf, len, call_type_p, caller_p);
-       if (ret != 0) {
-               printk(PRELOAD_PREFIX "Invalid message pointers!\n");
-               return 0;
-       }
-
-       ret = preload_threads_get_drop(current);
-       if (ret > 0)
-               return 0;
-
-       buf = kmalloc(len, GFP_ATOMIC);
-       if (buf == NULL) {
-               printk(PRELOAD_PREFIX "No mem for buffer! Size = %d\n", len);
-               return 0;
-       }
-
-       ret = read_proc_vm_atomic(current, (unsigned long)user_buf, buf, len);
-       if (ret < 0) {
-               printk(PRELOAD_PREFIX "Cannot copy data from userspace! Size = "
-                                     "%d ptr 0x%lx ret %d\n", len,
-                                     (unsigned long)user_buf, ret);
-               goto write_msg_fail;
-       }
-
-       /* Evaluating call_type and caller offset in message:
-        * data offset = data pointer - beginning of the message.
-        */
-       call_type_offset = (unsigned long)(call_type_p - user_buf);
-       caller_offset = (unsigned long)(caller_p - user_buf);
-
-       __write_data_to_msg(buf, len, call_type_offset, caller_offset,
-                           caller_addr);
-
-       ret = swap_msg_raw(buf, len);
-       if (ret != len)
-               printk(PRELOAD_PREFIX "Error writing probe lib message\n");
-
-write_msg_fail:
-       kfree(buf);
-
-       return 0;
-}
-
-
-
-
-
-
-
-
-
-static int get_caller_handler(struct uprobe *p, struct pt_regs *regs)
-{
-       unsigned long caller;
-       int ret;
-
-       ret = preload_threads_get_caller(current, &caller);
-       if (ret != 0) {
-               caller = 0xbadbeef;
-               printk(PRELOAD_PREFIX "Error! Cannot get caller address for "
-                      "%d/%d\n", current->tgid, current->pid);
-       }
-
-       swap_put_uarg(regs, 0, caller);
-
-       return 0;
-}
-
-static int get_call_type_handler(struct uprobe *p, struct pt_regs *regs)
-{
-       unsigned char call_type;
-       int ret;
-
-       ret = preload_threads_get_call_type(current, &call_type);
-       if (ret != 0) {
-               call_type = 0xff;
-               printk(PRELOAD_PREFIX "Error! Cannot get call type for %d/%d\n",
-                      current->tgid, current->pid);
-       }
-
-       swap_put_uarg(regs, 0, call_type);
-
-       return 0;
-}
-
-
-
-
-
-
-int ph_get_caller_init(struct sspt_ip *ip)
-{
-       struct uprobe *up = &ip->uprobe;
-
-       up->pre_handler = get_caller_handler;
-
-       return 0;
-}
-
-void ph_get_caller_exit(struct sspt_ip *ip)
-{
-}
-
-int ph_get_call_type_init(struct sspt_ip *ip)
-{
-       struct uprobe *up = &ip->uprobe;
-
-       up->pre_handler = get_call_type_handler;
-
-       return 0;
-}
-
-void ph_get_call_type_exit(struct sspt_ip *ip)
-{
-}
-
-int ph_write_msg_init(struct sspt_ip *ip)
-{
-       struct uprobe *up = &ip->uprobe;
-
-       up->pre_handler = write_msg_handler;
-
-       return 0;
-}
-
-void ph_write_msg_exit(struct sspt_ip *ip)
-{
-}
-
-void ph_set_handler_dentry(struct dentry *dentry)
-{
-       handler_dentry = dentry;
-}
-
-
-int ph_uprobe_init(struct sspt_ip *ip)
-{
-       struct uretprobe *rp = &ip->retprobe;
-
-       rp->entry_handler = preload_us_entry;
-       rp->handler = preload_us_ret;
-       /* FIXME actually additional data_size is needed only when we jump
-        * to dlopen */
-       preload_set_rp_data_size(rp);
-
-       return 0;
-}
-
-void ph_uprobe_exit(struct sspt_ip *ip)
-{
-}
diff --git a/preload/preload_handlers.h b/preload/preload_handlers.h
deleted file mode 100644 (file)
index 04e4360..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __PRELOAD_HANDLERS_H__
-#define __PRELOAD_HANDLERS_H__
-
-struct sspt_ip;
-struct dentry;
-
-int ph_uprobe_init(struct sspt_ip *ip);
-void ph_uprobe_exit(struct sspt_ip *ip);
-
-int ph_get_caller_init(struct sspt_ip *ip);
-void ph_get_caller_exit(struct sspt_ip *ip);
-int ph_get_call_type_init(struct sspt_ip *ip);
-void ph_get_call_type_exit(struct sspt_ip *ip);
-int ph_write_msg_init(struct sspt_ip *ip);
-void ph_write_msg_exit(struct sspt_ip *ip);
-void ph_set_handler_dentry(struct dentry *dentry);
-
-#endif /* __PRELOAD_HANDLERS_H__ */
index b614042..ce6edb7 100644 (file)
-#include <linux/module.h>
-#include <linux/dcache.h>
+#include <linux/slab.h>
 #include <linux/namei.h>
-#include <linux/mman.h>
-#include <linux/err.h>
-#include <linux/types.h>
-#include <kprobe/swap_kprobes.h>
 #include <kprobe/swap_kprobes_deps.h>
-#include <us_manager/sspt/sspt_proc.h>
-#include <us_manager/sspt/sspt_ip.h>
-#include <us_manager/callbacks.h>
 #include <writer/kernel_operations.h>
+#include <writer/swap_msg.h>
+#include <us_manager/sspt/sspt_ip.h>
+#include <us_manager/sspt/sspt_page.h>
+#include <us_manager/sspt/sspt_file.h>
+#include <loader/loader_pd.h>
+#include <loader/loader_module.h>
 #include <master/swap_initializer.h>
 #include "preload.h"
-#include "preload_probe.h"
-#include "preload_debugfs.h"
 #include "preload_module.h"
-#include "preload_storage.h"
+#include "preload_debugfs.h"
 #include "preload_control.h"
 #include "preload_threads.h"
-#include "preload_pd.h"
 
+#define page_to_proc(page) ((page)->file->proc)
+#define ip_to_proc(ip) page_to_proc((ip)->page)
+#define urp_to_ip(rp) container_of(rp, struct sspt_ip, retprobe)
 
-struct us_priv {
-       struct pt_regs regs;
-       unsigned long arg0;
-       unsigned long arg1;
-       unsigned long raddr;
-       unsigned long origin;
+enum {
+       /* task preload flags */
+       HANDLER_RUNNING = 0x1
 };
 
-static atomic_t dentry_balance = ATOMIC_INIT(0);
+static struct dentry *handler_dentry = NULL;
 
-enum preload_status_t {
-       SWAP_PRELOAD_NOT_READY = 0,
-       SWAP_PRELOAD_READY = 1,
-       SWAP_PRELOAD_RUNNING = 2
-};
-
-static enum preload_status_t __preload_status = SWAP_PRELOAD_NOT_READY;
 
-static int __preload_cbs_start_h = -1;
-static int __preload_cbs_stop_h = -1;
+static inline struct pd_t *__get_process_data(struct uretprobe *rp)
+{
+       struct sspt_ip *ip = urp_to_ip(rp);
+       struct sspt_proc *proc = ip_to_proc(ip);
 
+       return lpd_get(proc);
+}
 
-static struct dentry *__get_dentry(struct dentry *dentry)
+static inline struct vm_area_struct *__get_vma_by_addr(struct task_struct *task,
+                                                      unsigned long caddr)
 {
-       atomic_inc(&dentry_balance);
-       return dget(dentry);
-}
+       struct vm_area_struct *vma = NULL;
 
+       if ((task == NULL) || (task->mm == NULL))
+               return NULL;
+       vma = find_vma_intersection(task->mm, caddr, caddr + 1);
 
+       return vma;
+}
 
-bool preload_module_is_running(void)
+static inline bool __is_probe_non_block(struct sspt_ip *ip)
 {
-       if (__preload_status == SWAP_PRELOAD_RUNNING)
+       if (ip->desc->info.pl_i.flags & SWAP_PRELOAD_NON_BLOCK_PROBE)
                return true;
 
        return false;
 }
 
-bool preload_module_is_ready(void)
+static inline bool __inverted(struct sspt_ip *ip)
 {
-       if (__preload_status == SWAP_PRELOAD_READY)
+       unsigned long flags = ip->desc->info.pl_i.flags;
+
+       if (flags & SWAP_PRELOAD_INVERTED_PROBE)
                return true;
 
        return false;
 }
 
-bool preload_module_is_not_ready(void)
+static inline bool __check_flag_and_call_type(struct sspt_ip *ip,
+                                             enum preload_call_type ct)
 {
-       if (__preload_status == SWAP_PRELOAD_NOT_READY)
+       bool inverted = __inverted(ip);
+
+       if (ct != NOT_INSTRUMENTED || inverted)
                return true;
 
        return false;
 }
 
-void preload_module_set_ready(void)
-{
-       __preload_status = SWAP_PRELOAD_READY;
-}
-
-void preload_module_set_running(void)
+static inline bool __is_handlers_call(struct vm_area_struct *caller,
+                                     struct pd_t *pd)
 {
-       __preload_status = SWAP_PRELOAD_RUNNING;
-}
-
-void preload_module_set_not_ready(void)
-{
-       __preload_status = SWAP_PRELOAD_NOT_READY;
-}
-
-struct dentry *get_dentry(const char *filepath)
-{
-       struct path path;
-       struct dentry *dentry = NULL;
+       struct hd_t *hd;
 
-       if (kern_path(filepath, LOOKUP_FOLLOW, &path) == 0) {
-               dentry = __get_dentry(path.dentry);
-               path_put(&path);
+       if (caller == NULL || caller->vm_file == NULL ||
+           caller->vm_file->f_path.dentry == NULL) {
+               return false;
        }
 
-       return dentry;
-}
+       hd = lpd_get_hd(pd, caller->vm_file->f_path.dentry);
+       if (hd != NULL)
+               return true;
 
-void put_dentry(struct dentry *dentry)
-{
-       atomic_dec(&dentry_balance);
-       dput(dentry);
+       return false;
 }
 
-static inline void __prepare_ujump(struct uretprobe_instance *ri,
-                                  struct pt_regs *regs,
-                                  unsigned long vaddr)
+static inline bool __should_drop(struct sspt_ip *ip, enum preload_call_type ct)
 {
-#ifdef CONFIG_ARM
-       ri->preload.use = true;
-       ri->preload.thumb = !!thumb_mode(regs);
-#endif /* CONFIG_ARM */
+       if (ct == NOT_INSTRUMENTED)
+               return true;
 
-       swap_set_instr_ptr(regs, vaddr);
+       return false;
 }
 
-static inline int __push(struct pt_regs *regs, void *buf, size_t len)
+static inline int __msg_sanitization(char *user_msg, size_t len,
+                                    char *call_type_p, char *caller_p)
 {
-       unsigned long sp = swap_get_stack_ptr(regs) - len;
-
-       sp = PTR_ALIGN(sp, sizeof(unsigned long));
-       if (copy_to_user((void __user *)sp, buf, len))
-               return -EIO;
-       swap_set_stack_ptr(regs, sp);
+       if ((call_type_p < user_msg) || (call_type_p > user_msg + len) ||
+           (caller_p < user_msg) || (caller_p > user_msg + len))
+               return -EINVAL;
 
        return 0;
 }
 
-static inline void __save_uregs(struct uretprobe_instance *ri,
-                               struct pt_regs *regs)
-{
-       struct us_priv *priv = (struct us_priv *)ri->data;
 
-       memcpy(ri->data, regs, sizeof(*regs));
-       priv->arg0 = swap_get_arg(regs, 0);
-       priv->arg1 = swap_get_arg(regs, 1);
-       priv->raddr = swap_get_ret_addr(regs);
-}
 
-static inline void __restore_uregs(struct uretprobe_instance *ri,
-                                  struct pt_regs *regs)
-{
-       struct us_priv *priv = (struct us_priv *)ri->data;
-
-       memcpy(regs, ri->data, sizeof(*regs));
-       swap_set_arg(regs, 0, priv->arg0);
-       swap_set_arg(regs, 1, priv->arg1);
-       swap_set_ret_addr(regs, priv->raddr);
-#ifndef CONFIG_ARM
-       /* need to do it only on x86 */
-       regs->EREG(ip) -= 1;
-#endif /* !CONFIG_ARM */
-       /* we have just restored the registers => no need to do it in
-        * trampoline_uprobe_handler */
-       ri->ret_addr = NULL;
-}
 
-static inline void print_regs(const char *prefix, struct pt_regs *regs,
-                             struct uretprobe_instance *ri, struct hd_t *hd)
-{
-       struct dentry *dentry = preload_pd_get_dentry(hd);
-
-#ifdef CONFIG_ARM
-       printk(PRELOAD_PREFIX "%s[%d/%d] %s (%d) %s addr(%08lx), "
-              "r0(%08lx), r1(%08lx), r2(%08lx), r3(%08lx), "
-              "r4(%08lx), r5(%08lx), r6(%08lx), r7(%08lx), "
-              "sp(%08lx), lr(%08lx), pc(%08lx)\n",
-              current->comm, current->tgid, current->pid,
-              dentry != NULL ? (char *)(dentry->d_name.name) :
-                               (char *)("NULL"),
-              (int)preload_pd_get_state(hd),
-              prefix, (unsigned long)ri->rp->up.addr,
-              regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3,
-              regs->ARM_r4, regs->ARM_r5, regs->ARM_r6, regs->ARM_r7,
-              regs->ARM_sp, regs->ARM_lr, regs->ARM_pc);
-#else /* !CONFIG_ARM */
-       printk(PRELOAD_PREFIX "%s[%d/%d] %s (%d) %s addr(%08lx), "
-              "ip(%08lx), arg0(%08lx), arg1(%08lx), raddr(%08lx)\n",
-              current->comm, current->tgid, current->pid,
-              dentry != NULL ? (char *)(dentry->d_name.name) :
-                               (char *)("NULL"),
-              (int)preload_pd_get_state(hd),
-              prefix, (unsigned long)ri->rp->up.addr,
-              regs->EREG(ip), swap_get_arg(regs, 0), swap_get_arg(regs, 1),
-              swap_get_ret_addr(regs));
-#endif /* CONFIG_ARM */
-}
-
-static inline unsigned long __get_r_debug_off(struct vm_area_struct *linker_vma)
-{
-       unsigned long start_addr;
-       unsigned long offset = preload_debugfs_r_debug_offset();
-
-       if (linker_vma == NULL)
-               return 0;
-
-       start_addr = linker_vma->vm_start;
-
-       return (offset ? start_addr + offset : 0);
-}
-
-static struct vm_area_struct *__get_linker_vma(struct task_struct *task)
+static unsigned long __do_preload_entry(struct uretprobe_instance *ri,
+                                       struct pt_regs *regs,
+                                       struct hd_t *hd)
 {
-       struct vm_area_struct *vma = NULL;
-       struct bin_info *ld_info;
+       struct sspt_ip *ip = container_of(ri->rp, struct sspt_ip, retprobe);
+       unsigned long offset = ip->desc->info.pl_i.handler;
+       unsigned long vaddr = 0;
+       unsigned long base;
+       unsigned long disable_addr;
+       unsigned long caddr;
+       struct vm_area_struct *cvma;
+       enum preload_call_type ct;
 
-       ld_info = preload_storage_get_linker_info();
-       if (ld_info == NULL) {
-               printk(PRELOAD_PREFIX "Cannot get linker info [%u %u %s]!\n",
-                      task->tgid, task->pid, task->comm);
-               return NULL;
-       }
+       base = lpd_get_handlers_base(hd);
+       if (base == 0)
+               return 0;       /* handlers isn't mapped */
 
-       for (vma = task->mm->mmap; vma; vma = vma->vm_next) {
-               if (vma->vm_file && vma->vm_flags & VM_EXEC
-                   && vma->vm_file->f_dentry == ld_info->dentry) {
-                               preload_storage_put_linker_info(ld_info);
-                               return vma;
+       /* jump to preloaded handler */
+       vaddr = base + offset;
+       if (vaddr) {
+               caddr = get_regs_ret_func(regs);
+               cvma = __get_vma_by_addr(current, caddr);
+               ct = pc_call_type(ip, (void *)caddr);
+               disable_addr = __is_probe_non_block(ip) ? ip->orig_addr : 0;
+
+               /* jump only if caller is instumented and it is not a system lib -
+                * this leads to some errors */
+               if (cvma != NULL && cvma->vm_file != NULL &&
+                       cvma->vm_file->f_dentry != NULL) {
+
+                       struct dentry *dentry = cvma->vm_file->f_dentry;
+                       struct pd_t *pd = lpd_get_parent_pd(hd);
+
+                       if (!pc_check_dentry_is_ignored(dentry) &&
+                           __check_flag_and_call_type(ip, ct) &&
+                           !__is_handlers_call(cvma, pd)) {
+
+                               bool drop = __should_drop(ip, ct);
+                               if (pt_set_data(current, caddr,
+                                                            ct, disable_addr,
+                                                            drop) != 0)
+                                       printk(PRELOAD_PREFIX "Error! Failed "
+                                              "to set caller 0x%lx for "
+                                              "%d/%d\n", caddr,
+                                              current->tgid,
+                                              current->pid);
+                               /* args are not changed */
+                               loader_module_prepare_ujump(ri, regs, vaddr);
+                               if (disable_addr == 0)
+                                       pt_set_flags(current,
+                                                         HANDLER_RUNNING);
+                       }
                }
        }
 
-       preload_storage_put_linker_info(ld_info);
-       return NULL;
+       return vaddr;
 }
 
-static inline struct vm_area_struct *__get_vma_by_addr(struct task_struct *task,
-                                                       unsigned long caller_addr)
+static int preload_us_entry(struct uretprobe_instance *ri, struct pt_regs *regs)
 {
-       struct vm_area_struct *vma = NULL;
-
-       if (task->mm == NULL)
-               return NULL;
-       vma = find_vma_intersection(task->mm, caller_addr, caller_addr + 1);
+       struct pd_t *pd = __get_process_data(ri->rp);
+       struct hd_t *hd;
+       unsigned long old_pc = swap_get_instr_ptr(regs);
+       unsigned long flags = pt_get_flags(current);
+       struct sspt_ip *ip = container_of(ri->rp, struct sspt_ip, retprobe);
+       unsigned long vaddr = 0;
 
-       return vma;
-}
+       if (handler_dentry == NULL)
+               goto out_set_orig;
 
+       if ((flags & HANDLER_RUNNING) ||
+           pt_check_disabled_probe(current, ip->orig_addr))
+               goto out_set_orig;
 
+       hd = lpd_get_hd(pd, handler_dentry);
+       if (hd == NULL)
+               goto out_set_orig;
 
+       if ((flags & HANDLER_RUNNING) ||
+               pt_check_disabled_probe(current, ip->orig_addr))
+               goto out_set_orig;
 
+       if (lpd_get_state(hd) == NOT_LOADED ||
+           lpd_get_state(hd) == FAILED)
+               vaddr = loader_not_loaded_entry(ri, regs, pd, hd);
+       else if (lpd_get_state(hd) == LOADED)
+               vaddr =__do_preload_entry(ri, regs, hd);
 
+out_set_orig:
+       loader_set_priv_origin(ri, vaddr);
 
+       /* PC change check */
+       return old_pc != swap_get_instr_ptr(regs);
+}
 
+static void __do_preload_ret(struct uretprobe_instance *ri, struct hd_t *hd)
+{
+       struct sspt_ip *ip = container_of(ri->rp, struct sspt_ip, retprobe);
+       unsigned long flags = pt_get_flags(current);
+       unsigned long offset = ip->desc->info.pl_i.handler;
+       unsigned long vaddr = 0;
 
+       if ((flags & HANDLER_RUNNING) ||
+           pt_check_disabled_probe(current, ip->orig_addr)) {
+               bool non_blk_probe = __is_probe_non_block(ip);
+
+               /* drop the flag if the handler has completed */
+               vaddr = lpd_get_handlers_base(hd) + offset;
+               if (vaddr && (loader_get_priv_origin(ri) == vaddr)) {
+                       if (pt_put_data(current) != 0)
+                               printk(PRELOAD_PREFIX "Error! Failed to put "
+                                      "caller slot for %d/%d\n", current->tgid,
+                                      current->pid);
+                       if (!non_blk_probe) {
+                               flags &= ~HANDLER_RUNNING;
+                               pt_set_flags(current, flags);
+                       }
+               }
+       }
+}
 
-static bool __is_proc_mmap_mappable(struct task_struct *task)
+static int preload_us_ret(struct uretprobe_instance *ri, struct pt_regs *regs)
 {
-       struct vm_area_struct *linker_vma = __get_linker_vma(task);
-       struct sspt_proc *proc;
-       unsigned long r_debug_addr;
-       unsigned int state;
-       enum { r_state_offset = sizeof(int) + sizeof(void *) + sizeof(long) };
+       struct pd_t *pd = __get_process_data(ri->rp);
+       struct hd_t *hd;
 
-       if (linker_vma == NULL)
-               return false;
+       if (handler_dentry == NULL)
+               return 0;
 
-       r_debug_addr = __get_r_debug_off(linker_vma);
-       if (r_debug_addr == 0)
-               return false;
+       hd = lpd_get_hd(pd, handler_dentry);
+       if (hd == NULL)
+               return 0;
 
-       r_debug_addr += r_state_offset;
-       proc = sspt_proc_get_by_task(task);
-       if (proc) {
-               proc->r_state_addr = r_debug_addr;
-               sspt_proc_put(proc);
+       switch (lpd_get_state(hd)) {
+       case NOT_LOADED:
+               /* loader has not yet been mapped... just ignore */
+               break;
+       case LOADING:
+               loader_loading_ret(ri, regs, pd, hd);
+               break;
+       case LOADED:
+               __do_preload_ret(ri, hd);
+               break;
+       case FAILED:
+               loader_failed_ret(ri, regs, pd, hd);
+               break;
+       case ERROR:
+       default:
+               break;
        }
 
-       if (get_user(state, (unsigned long *)r_debug_addr))
-               return false;
-
-       return !state;
+       return 0;
 }
 
-static bool __should_we_preload_handlers(struct task_struct *task,
-                                        struct pt_regs *regs)
-{
-       unsigned long caller_addr = get_regs_ret_func(regs);
-       struct vm_area_struct *cvma = __get_vma_by_addr(current, caller_addr);
-
-       if (!__is_proc_mmap_mappable(task) ||
-           ((cvma != NULL) && (cvma->vm_file != NULL) &&
-           (cvma->vm_file->f_path.dentry != NULL) &&
-           preload_control_check_dentry_is_ignored(cvma->vm_file->f_path.dentry)))
-               return false;
 
-       return true;
-}
 
 
 
+static void __write_data_to_msg(char *msg, size_t len,
+                               unsigned long call_type_off,
+                               unsigned long caller_off,
+                               unsigned long caller_addr)
+{
+       unsigned char call_type = 0;
+       unsigned long caller = 0;
+       int ret;
 
+       if (caller_addr != 0) {
+               caller = caller_addr;
+               call_type =
+                   pc_call_type_always_inst((void *)caller);
+       } else {
+               ret = pt_get_caller(current, &caller);
+               if (ret != 0) {
+                       caller = 0xbadbeef;
+                       printk(PRELOAD_PREFIX "Error! Cannot get caller address"
+                              " for %d/%d\n", current->tgid, current->pid);
+               }
 
-struct mmap_priv {
-       struct dentry *dentry;
-};
+               ret = pt_get_call_type(current, &call_type);
+               if (ret != 0) {
+                       call_type = 0xff;
+                       printk(PRELOAD_PREFIX "Error! Cannot get call type for "
+                              "%d/%d\n", current->tgid, current->pid);
+               }
+       }
 
-static inline bool check_prot(unsigned long prot)
-{
-       return !!((prot & PROT_READ) && (prot & PROT_EXEC));
+       /* Using the same types as in the library. */
+       *(uint32_t *)(msg + call_type_off) = (uint32_t)call_type;
+       *(uintptr_t *)(msg + caller_off) = (uintptr_t)caller;
 }
 
-static int mmap_entry_handler(struct kretprobe_instance *ri,
-                             struct pt_regs *regs)
+static int write_msg_handler(struct uprobe *p, struct pt_regs *regs)
 {
-       struct file *file = (struct file *)swap_get_karg(regs, 0);
-       unsigned long prot = swap_get_karg(regs, 3);
-       struct mmap_priv *priv = (struct mmap_priv *)ri->data;
-       struct task_struct *task = current->group_leader;
-       struct dentry *dentry, *loader_dentry;
-       struct pd_t *pd;
-       struct hd_t *hd;
-       struct sspt_proc *proc;
+       char *user_buf;
+       char *buf;
+       char *caller_p;
+       char *call_type_p;
+       size_t len;
+       unsigned long caller_offset;
+       unsigned long call_type_offset;
+       unsigned long caller_addr;
+       int ret;
 
-       priv->dentry = NULL;
-       if (!check_prot(prot))
-               return 0;
+       /* FIXME: swap_get_uarg uses get_user(), it might sleep */
+       user_buf = (char *)swap_get_uarg(regs, 0);
+       len = swap_get_uarg(regs, 1);
+       call_type_p = (char *)swap_get_uarg(regs, 2);
+       caller_p = (char *)swap_get_uarg(regs, 3);
+       caller_addr = swap_get_uarg(regs, 4);
 
-       if (!file)
+       ret = __msg_sanitization(user_buf, len, call_type_p, caller_p);
+       if (ret != 0) {
+               printk(PRELOAD_PREFIX "Invalid message pointers!\n");
                return 0;
+       }
 
-       dentry = file->f_dentry;
-       if (dentry == NULL)
+       ret = pt_get_drop(current);
+       if (ret > 0)
                return 0;
 
-       loader_dentry = preload_debugfs_get_loader_dentry();
-       if (dentry == loader_dentry) {
-               priv->dentry = loader_dentry;
+       buf = kmalloc(len, GFP_ATOMIC);
+       if (buf == NULL) {
+               printk(PRELOAD_PREFIX "No mem for buffer! Size = %d\n", len);
                return 0;
        }
 
-       proc = sspt_proc_by_task(task);
-       if (!proc)
-               return 0;
-
-       pd = preload_pd_get(proc);
-       if (pd == NULL) {
-               printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n",
-                      __LINE__, current->tgid, current->comm);
-               return 0;
+       ret = read_proc_vm_atomic(current, (unsigned long)user_buf, buf, len);
+       if (ret < 0) {
+               printk(PRELOAD_PREFIX "Cannot copy data from userspace! Size = "
+                                     "%d ptr 0x%lx ret %d\n", len,
+                                     (unsigned long)user_buf, ret);
+               goto write_msg_fail;
        }
 
-       hd = preload_pd_get_hd(pd, dentry);
-       if (hd != NULL)
-               priv->dentry = preload_pd_get_dentry(hd);
+       /* Evaluating call_type and caller offset in message:
+        * data offset = data pointer - beginning of the message.
+        */
+       call_type_offset = (unsigned long)(call_type_p - user_buf);
+       caller_offset = (unsigned long)(caller_p - user_buf);
 
-       return 0;
-}
+       __write_data_to_msg(buf, len, call_type_offset, caller_offset,
+                           caller_addr);
 
-static int mmap_ret_handler(struct kretprobe_instance *ri,
-                           struct pt_regs *regs)
-{
-       struct mmap_priv *priv = (struct mmap_priv *)ri->data;
-       struct task_struct *task = current->group_leader;
-       struct pd_t *pd;
-       struct hd_t *hd;
-       struct sspt_proc *proc;
-       struct dentry *loader_dentry;
-       unsigned long vaddr;
+       ret = swap_msg_raw(buf, len);
+       if (ret != len)
+               printk(PRELOAD_PREFIX "Error writing probe lib message\n");
 
-       if (!task->mm)
-               return 0;
+write_msg_fail:
+       kfree(buf);
 
-       if (priv->dentry == NULL)
-               return 0;
+       return 0;
+}
 
-       vaddr = (unsigned long)regs_return_value(regs);
-       if (IS_ERR_VALUE(vaddr))
-               return 0;
 
-       proc = sspt_proc_by_task(task);
-       if (!proc)
-               return 0;
 
-       pd = preload_pd_get(proc);
-       if (pd == NULL) {
-               printk(PRELOAD_PREFIX "%d: No process data! Current %d %s\n",
-                      __LINE__, current->tgid, current->comm);
-               return 0;
-       }
 
-       loader_dentry = preload_debugfs_get_loader_dentry();
-       if (priv->dentry == loader_dentry)
-               preload_pd_set_loader_base(pd, vaddr);
 
 
-       hd = preload_pd_get_hd(pd, priv->dentry);
-       if (hd != NULL)
-               preload_pd_set_handlers_base(hd, vaddr);
 
-       return 0;
-}
 
-static struct kretprobe mmap_rp = {
-       .kp.symbol_name = "do_mmap_pgoff",
-       .data_size = sizeof(struct mmap_priv),
-       .entry_handler = mmap_entry_handler,
-       .handler = mmap_ret_handler
-};
 
-static void preload_start_cb(void)
+static int get_caller_handler(struct uprobe *p, struct pt_regs *regs)
 {
-       int res;
+       unsigned long caller;
+       int ret;
 
-       res = swap_register_kretprobe(&mmap_rp);
-       if (res != 0)
-               printk(KERN_ERR PRELOAD_PREFIX "Registering do_mmap_pgoff probe failed\n");
-}
+       ret = pt_get_caller(current, &caller);
+       if (ret != 0) {
+               caller = 0xbadbeef;
+               printk(PRELOAD_PREFIX "Error! Cannot get caller address for "
+                      "%d/%d\n", current->tgid, current->pid);
+       }
 
-static void preload_stop_cb(void)
-{
-       swap_unregister_kretprobe(&mmap_rp);
+       swap_put_uarg(regs, 0, caller);
+
+       return 0;
 }
 
-static unsigned long __not_loaded_entry(struct uretprobe_instance *ri,
-                                       struct pt_regs *regs,
-                                       struct pd_t *pd, struct hd_t *hd)
+static int get_call_type_handler(struct uprobe *p, struct pt_regs *regs)
 {
-       char __user *path = NULL;
-       unsigned long vaddr = 0;
-       unsigned long base;
+       unsigned char call_type;
+       int ret;
 
-       /* if linker is still doing its work, we do nothing */
-       if (!__should_we_preload_handlers(current, regs))
-               return 0;
+       ret = pt_get_call_type(current, &call_type);
+       if (ret != 0) {
+               call_type = 0xff;
+               printk(PRELOAD_PREFIX "Error! Cannot get call type for %d/%d\n",
+                      current->tgid, current->pid);
+       }
 
-       base = preload_pd_get_loader_base(pd);
-       if (base == 0)
-               return 0;   /* loader isn't mapped */
+       swap_put_uarg(regs, 0, call_type);
 
-       /* jump to loader code if ready */
-       vaddr = base + preload_debugfs_get_loader_offset();
-       if (vaddr) {
-               /* save original regs state */
-               __save_uregs(ri, regs);
-               print_regs("ORIG", regs, ri, hd);
+       return 0;
+}
 
-               path = preload_pd_get_path(pd, hd);
 
-               /* set dlopen args: filename, flags */
-               swap_set_arg(regs, 0, (unsigned long)path/*swap_get_stack_ptr(regs)*/);
-               swap_set_arg(regs, 1, 2 /* RTLD_NOW */);
 
-               /* do the jump to dlopen */
-               __prepare_ujump(ri, regs, vaddr);
-               /* set new state */
-               preload_pd_set_state(hd, LOADING);
-       }
 
-       return vaddr;
-}
 
-static void __loading_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
-                         struct pd_t *pd, struct hd_t *hd)
+struct dentry *get_dentry(const char *filepath)
 {
-       struct us_priv *priv = (struct us_priv *)ri->data;
-       unsigned long vaddr = 0;
+       struct path path;
+       struct dentry *dentry = NULL;
 
-       /* check if preloading has been completed */
-       vaddr = preload_pd_get_loader_base(pd) +
-               preload_debugfs_get_loader_offset();
-       if (vaddr && (priv->origin == vaddr)) {
-               preload_pd_set_handle(hd,
-                                     (void __user *)regs_return_value(regs));
-
-               /* restore original regs state */
-               __restore_uregs(ri, regs);
-               print_regs("REST", regs, ri, hd);
-               /* check if preloading done */
-
-               if (preload_pd_get_handle(hd)) {
-                       preload_pd_set_state(hd, LOADED);
-               } else {
-                       preload_pd_dec_attempts(hd);
-                       preload_pd_set_state(hd, FAILED);
-               }
+       if (kern_path(filepath, LOOKUP_FOLLOW, &path) == 0) {
+               dentry = dget(path.dentry);
+               path_put(&path);
        }
+
+       return dentry;
 }
 
-static void __failed_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
-                        struct pd_t *pd, struct hd_t *hd)
+void put_dentry(struct dentry *dentry)
 {
-       if (preload_pd_get_attempts(hd))
-               preload_pd_set_state(hd, NOT_LOADED);
+       dput(dentry);
 }
 
+int pm_get_caller_init(struct sspt_ip *ip)
+{
+       struct uprobe *up = &ip->uprobe;
 
+       up->pre_handler = get_caller_handler;
 
-unsigned long preload_not_loaded_entry(struct uretprobe_instance *ri,
-                                      struct pt_regs *regs, struct pd_t *pd,
-                                      struct hd_t *hd)
-{
-       return __not_loaded_entry(ri, regs, pd, hd);
+       return 0;
 }
 
-void preload_loading_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
-                        struct pd_t *pd, struct hd_t *hd)
+void pm_get_caller_exit(struct sspt_ip *ip)
 {
-       __loading_ret(ri, regs, pd, hd);
 }
 
-void preload_failed_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
-                       struct pd_t *pd, struct hd_t *hd)
+int pm_get_call_type_init(struct sspt_ip *ip)
 {
-       __failed_ret(ri, regs, pd, hd);
+       struct uprobe *up = &ip->uprobe;
+
+       up->pre_handler = get_call_type_handler;
+
+       return 0;
 }
 
-void preload_module_prepare_ujump(struct uretprobe_instance *ri,
-                                 struct pt_regs *regs, unsigned long addr)
+void pm_get_call_type_exit(struct sspt_ip *ip)
 {
-       __prepare_ujump(ri, regs, addr);
 }
 
-void preload_set_rp_data_size(struct uretprobe *rp)
+int pm_write_msg_init(struct sspt_ip *ip)
 {
-       rp->data_size = sizeof(struct us_priv);
+       struct uprobe *up = &ip->uprobe;
+
+       up->pre_handler = write_msg_handler;
+
+       return 0;
 }
 
-void preload_set_priv_origin(struct uretprobe_instance *ri, unsigned long addr)
+void pm_write_msg_exit(struct sspt_ip *ip)
 {
-       struct us_priv *priv = (struct us_priv *)ri->data;
-
-       priv->origin = addr;
 }
 
-unsigned long preload_get_priv_origin(struct uretprobe_instance *ri)
+int pm_set_handler(char *path)
 {
-       struct us_priv *priv = (struct us_priv *)ri->data;
+       struct dentry *dentry;
+       int ret;
 
-    return priv->origin;
-}
+       if (handler_dentry != NULL)
+               put_dentry(handler_dentry);
 
+       dentry = get_dentry(path);
 
-int preload_set(void)
-{
-       if (preload_module_is_running())
-               return -EBUSY;
+       if (dentry == NULL) {
+               printk(KERN_WARNING PRELOAD_PREFIX "Error! Cannot get handler %s\n",
+                      path);
+               return -EINVAL;
+       }
+
+       ret = loader_add_handler(path);
+       if (ret != 0)
+               return ret;
+
+       handler_dentry = dentry;
 
        return 0;
 }
 
-void preload_unset(void)
+
+int pm_uprobe_init(struct sspt_ip *ip)
 {
-       swap_unregister_kretprobe(&mmap_rp);
-       /*module_put(THIS_MODULE);*/
-       preload_module_set_not_ready();
+       struct uretprobe *rp = &ip->retprobe;
 
+       rp->entry_handler = preload_us_entry;
+       rp->handler = preload_us_ret;
+       /* FIXME actually additional data_size is needed only when we jump
+        * to dlopen */
+       loader_set_rp_data_size(rp);
+
+       return 0;
 }
 
+void pm_uprobe_exit(struct sspt_ip *ip)
+{
+}
 
-static int preload_module_init(void)
+static int pm_init(void)
 {
        int ret;
 
-       ret = preload_debugfs_init();
+       ret = pd_init();
        if (ret)
                goto out_err;
 
-       ret = preload_storage_init();
-       if (ret)
-               goto exit_debugfs;
-
-       ret = preload_pd_init();
-       if (ret)
-               goto exit_storage;
-
-       /* TODO do not forget to remove set (it is just for debugging) */
-       ret = preload_set();
-       if (ret)
-               goto exit_pd;
-
-       ret = preload_control_init();
+       ret = pc_init();
        if (ret)
-               goto exit_set;
+               goto control_init_fail;
 
-       ret = preload_threads_init();
+       ret = pt_init();
        if (ret)
-               goto exit_control;
+               goto threads_init_fail;
 
        ret = register_preload_probes();
        if (ret)
-               goto exit_threads;
-
-       __preload_cbs_start_h = us_manager_reg_cb(START_CB, preload_start_cb);
-       if (__preload_cbs_start_h < 0)
-               goto exit_start_cb;
-
-       __preload_cbs_stop_h = us_manager_reg_cb(STOP_CB, preload_stop_cb);
-       if (__preload_cbs_stop_h < 0)
-               goto exit_stop_cb;
+               goto probes_register_fail;
 
        return 0;
 
-exit_stop_cb:
-       us_manager_unreg_cb(__preload_cbs_start_h);
-
-exit_start_cb:
-       unregister_preload_probes();
-
-exit_threads:
-       preload_threads_exit();
+probes_register_fail:
+       pt_exit();
 
-exit_control:
-       preload_control_exit();
+threads_init_fail:
+       pc_exit();
 
-exit_set:
-       preload_unset();
-
-exit_pd:
-       preload_pd_uninit();
-
-exit_storage:
-       preload_storage_exit();
-
-exit_debugfs:
-       preload_debugfs_exit();
+control_init_fail:
+       pd_exit();
 
 out_err:
        return ret;
 }
 
-static void preload_module_exit(void)
+static void pm_exit(void)
 {
-       int balance;
-
-       us_manager_unreg_cb(__preload_cbs_start_h);
-       us_manager_unreg_cb(__preload_cbs_stop_h);
        unregister_preload_probes();
-       preload_threads_exit();
-       preload_control_exit();
-       preload_unset();
-       preload_pd_uninit();
-       preload_storage_exit();
-       preload_debugfs_exit();
-
-       balance = atomic_read(&dentry_balance);
-       atomic_set(&dentry_balance, 0);
+       pt_exit();
+       pc_exit();
+       pd_exit();
 
-       WARN(balance, "Bad GET/PUT dentry balance: %d\n", balance);
+       if (handler_dentry != NULL)
+               put_dentry(handler_dentry);
 }
 
-SWAP_LIGHT_INIT_MODULE(NULL, preload_module_init, preload_module_exit,
-                      NULL, NULL);
-
+SWAP_LIGHT_INIT_MODULE(NULL, pm_init, pm_exit, NULL, NULL);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SWAP Preload Module");
-MODULE_AUTHOR("Vasiliy Ulyanov <v.ulyanov@samsung.com>"
-              "Alexander Aksenov <a.aksenov@samsung.com>");
+MODULE_AUTHOR("Alexander Aksenov <a.aksenov@samsung.com>");
index 7b0ce2d..b3f5c78 100644 (file)
@@ -1,41 +1,21 @@
 #ifndef __PRELOAD_MODULE_H__
 #define __PRELOAD_MODULE_H__
 
-#include <linux/types.h>
-
+struct sspt_ip;
 struct dentry;
-struct pd_t;
-struct hd_t;
-struct uretprobe;
-struct uretprobe_instance;
-
-bool preload_module_is_ready(void);
-bool preload_module_is_running(void);
-bool preload_module_is_not_ready(void);
-void preload_module_set_ready(void);
-void preload_module_set_running(void);
-void preload_module_set_not_ready(void);
 
+int pm_uprobe_init(struct sspt_ip *ip);
+void pm_uprobe_exit(struct sspt_ip *ip);
 
-void preload_module_set_handler_dentry(struct dentry *dentry);
+int pm_get_caller_init(struct sspt_ip *ip);
+void pm_get_caller_exit(struct sspt_ip *ip);
+int pm_get_call_type_init(struct sspt_ip *ip);
+void pm_get_call_type_exit(struct sspt_ip *ip);
+int pm_write_msg_init(struct sspt_ip *ip);
+void pm_write_msg_exit(struct sspt_ip *ip);
+int pm_set_handler(char *path);
 
 struct dentry *get_dentry(const char *filepath);
 void put_dentry(struct dentry *dentry);
 
-void preload_module_prepare_ujump(struct uretprobe_instance *ri,
-                                 struct pt_regs *regs, unsigned long addr);
-
-unsigned long preload_not_loaded_entry(struct uretprobe_instance *ri,
-                                      struct pt_regs *regs, struct pd_t *pd,
-                                      struct hd_t *hd);
-void preload_loading_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
-                        struct pd_t *pd, struct hd_t *hd);
-void preload_failed_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
-                       struct pd_t *pd, struct hd_t *hd);
-
-void preload_set_rp_data_size(struct uretprobe *rp);
-void preload_set_priv_origin(struct uretprobe_instance *ri, unsigned long addr);
-unsigned long preload_get_priv_origin(struct uretprobe_instance *ri);
-
-
 #endif /* __PRELOAD_MODULE_H__ */
diff --git a/preload/preload_pd.h b/preload/preload_pd.h
deleted file mode 100644 (file)
index 9a92b42..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef __PRELOAD_PD_H__
-#define __PRELOAD_PD_H__
-
-struct pd_t;
-struct hd_t;
-struct sspt_proc;
-struct dentry;
-struct list_head;
-
-/* process preload states */
-enum ps_t {
-       NOT_LOADED,
-       LOADING,
-       LOADED,
-       FAILED,
-       ERROR
-};
-
-struct pd_t *preload_pd_get(struct sspt_proc *proc);
-unsigned long preload_pd_get_loader_base(struct pd_t *pd);
-void preload_pd_set_loader_base(struct pd_t *pd, unsigned long vaddr);
-
-struct hd_t *preload_pd_get_hd(struct pd_t *pd, struct dentry *dentry);
-struct dentry *preload_pd_get_dentry(struct hd_t *hd);
-struct pd_t *preload_pd_get_parent_pd(struct hd_t *hd);
-enum ps_t preload_pd_get_state(struct hd_t *hd);
-void preload_pd_set_state(struct hd_t *hd, enum ps_t state);
-unsigned long preload_pd_get_handlers_base(struct hd_t *hd);
-void preload_pd_set_handlers_base(struct hd_t *hd, unsigned long vaddr);
-void *preload_pd_get_handle(struct hd_t *hd);
-void preload_pd_set_handle(struct hd_t *hd, void __user *handle);
-long preload_pd_get_attempts(struct hd_t *hd);
-void preload_pd_dec_attempts(struct hd_t *hd);
-
-char __user *preload_pd_get_path(struct pd_t *pd, struct hd_t *hd);
-
-int preload_pd_init(void);
-void preload_pd_uninit(void);
-
-
-#endif /* __PRELOAD_PD_H__*/
index 4a44139..b15466d 100644 (file)
 #include "preload_probe.h"
 #include "preload.h"
 #include "preload_module.h"
-#include "preload_handlers.h"
-#include "preload_debugfs.h"
-
-static unsigned long long probes_count = 0;
 
 static int preload_info_copy(struct probe_info *dest,
                              const struct probe_info *source)
@@ -53,80 +49,26 @@ static struct uprobe *preload_get_uprobe(struct sspt_ip *ip)
        return &ip->retprobe.up;
 }
 
-/* We count all preload probes to know current state of the preload module:
- * if there are registered probes, than it is currently running, if there is no
- * probes, module is just ready to be used.
- *
- * If there was no registered probes and now they're appeared, change state to
- * 'running'.
- */
-static inline void inc_probes(void)
-{
-       if (probes_count == 0)
-               preload_module_set_running();
-
-       probes_count++;
-}
-
-/* If there were probes, but now there's no of them, change state to 'ready'.
- */
-static inline void dec_probes(void)
-{
-       if (unlikely(probes_count == 0))
-               printk(KERN_ERR PRELOAD_PREFIX "Trying to remove probe when there is no one!\n");
-
-       probes_count--;
-       if (probes_count == 0)
-               preload_module_set_ready();
-}
-
-/* Checks if preload can be in 'ready' state. It is so, if loader's dentry and
- * offset are specified.
- */
-static inline bool can_be_ready(void)
-{
-       struct dentry *dentry = preload_debugfs_get_loader_dentry();
-       unsigned long offset = preload_debugfs_get_loader_offset();
-
-       if (dentry != NULL && offset != 0)
-               return true;
-
-       return false;
-}
-
 /* Registers probe if preload is 'running' or 'ready'.
  */
 static int preload_register_probe(struct sspt_ip *ip)
 {
-       if (preload_module_is_not_ready()) {
-               if (can_be_ready()) {
-                       preload_module_set_ready();
-               } else {
-                       printk(PRELOAD_PREFIX "Module is not initialized!\n");
-                       return -EINVAL;
-               }
-       }
-
-       inc_probes();
-
        return swap_register_uretprobe(&ip->retprobe);
 }
 
 static void preload_unregister_probe(struct sspt_ip *ip, int disarm)
 {
        __swap_unregister_uretprobe(&ip->retprobe, disarm);
-
-       dec_probes();
 }
 
 static void preload_init(struct sspt_ip *ip)
 {
-       ph_uprobe_init(ip);
+       pm_uprobe_init(ip);
 }
 
 static void preload_uninit(struct sspt_ip *ip)
 {
-       ph_uprobe_exit(ip);
+       pm_uprobe_exit(ip);
 
        preload_info_cleanup(&ip->desc->info);
 }
@@ -170,12 +112,12 @@ static void get_caller_unregister_probe(struct sspt_ip *ip, int disarm)
 
 static void get_caller_init(struct sspt_ip *ip)
 {
-       ph_get_caller_init(ip);
+       pm_get_caller_init(ip);
 }
 
 static void get_caller_uninit(struct sspt_ip *ip)
 {
-       ph_get_caller_exit(ip);
+       pm_get_caller_exit(ip);
 
        get_caller_info_cleanup(&ip->desc->info);
 }
@@ -192,12 +134,12 @@ static struct probe_iface get_caller_iface = {
 
 static void get_call_type_init(struct sspt_ip *ip)
 {
-       ph_get_call_type_init(ip);
+       pm_get_call_type_init(ip);
 }
 
 static void get_call_type_uninit(struct sspt_ip *ip)
 {
-       ph_get_call_type_exit(ip);
+       pm_get_call_type_exit(ip);
 
        get_caller_info_cleanup(&ip->desc->info);
 }
@@ -214,7 +156,7 @@ static struct probe_iface get_call_type_iface = {
 
 static void write_msg_init(struct sspt_ip *ip)
 {
-       ph_write_msg_init(ip);
+       pm_write_msg_init(ip);
 }
 
 static int write_msg_reg(struct sspt_ip *ip)
@@ -224,7 +166,7 @@ static int write_msg_reg(struct sspt_ip *ip)
 
 static void write_msg_uninit(struct sspt_ip *ip)
 {
-       ph_write_msg_exit(ip);
+       pm_write_msg_exit(ip);
 
        get_caller_info_cleanup(&ip->desc->info);
 }
index c859afd..29ac33a 100644 (file)
@@ -22,8 +22,8 @@
  *
  */
 
-#ifndef __PRELOAD_PROBE_H__
-#define __PRELOAD_PROBE_H__
+#ifndef __PRELOAD_HANDLERS_PROBE_H__
+#define __PRELOAD_HANDLERS_PROBE_H__
 
 /* Probe flags description:
  *
@@ -64,4 +64,4 @@ struct write_msg_info {
 int register_preload_probes(void);
 void unregister_preload_probes(void);
 
-#endif /* __URETPROBE_H__ */
+#endif /* __PRELOAD_HANDLERS_PROBE_H__ */
diff --git a/preload/preload_storage.h b/preload/preload_storage.h
deleted file mode 100644 (file)
index 1fbd3a7..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __PRELOAD_STORAGE_H__
-#define __PRELOAD_STORAGE_H__
-
-struct list_head;
-struct dentry;
-
-struct bin_info {
-       char *path;
-       /* ghot */
-       struct dentry *dentry;
-};
-
-struct bin_info_el {
-       struct list_head list;
-       char *path;
-       /* ghot */
-       struct dentry *dentry;
-};
-
-
-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_add_handler(char *path);
-struct list_head *preload_storage_get_handlers(void);
-void preload_storage_put_handlers(void);
-
-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);
-
-int preload_storage_init(void);
-void preload_storage_exit(void);
-
-#endif /* __PRELOAD_HANDLERS_H__ */
index 12b74ef..675fc18 100644 (file)
@@ -8,7 +8,6 @@
 #include <kprobe/swap_ktd.h>
 #include "preload.h"
 #include "preload_threads.h"
-#include "preload_debugfs.h"
 
 struct preload_td {
        struct list_head slots;
@@ -55,13 +54,12 @@ static inline struct preload_td *get_preload_td(struct task_struct *task)
        return (struct preload_td *)swap_ktd(&preload_ktd, task);
 }
 
-unsigned long get_preload_flags(struct task_struct *task)
+unsigned long pt_get_flags(struct task_struct *task)
 {
        return get_preload_td(task)->flags;
 }
 
-void set_preload_flags(struct task_struct *task,
-                      unsigned long flags)
+void pt_set_flags(struct task_struct *task, unsigned long flags)
 {
        get_preload_td(task)->flags = flags;
 }
@@ -178,9 +176,8 @@ static inline struct thread_slot *__get_task_slot(struct task_struct *task)
 
 
 
-int preload_threads_set_data(struct task_struct *task, unsigned long caller,
-                            unsigned char call_type,
-                            unsigned long disable_addr, bool drop)
+int pt_set_data(struct task_struct *task, unsigned long caller,
+                unsigned char call_type, unsigned long disable_addr, bool drop)
 {
        struct preload_td *td = get_preload_td(task);
        struct thread_slot *slot;
@@ -206,7 +203,7 @@ set_data_done:
        return ret;
 }
 
-int preload_threads_get_caller(struct task_struct *task, unsigned long *caller)
+int pt_get_caller(struct task_struct *task, unsigned long *caller)
 {
        struct thread_slot *slot;
        int ret = 0;
@@ -224,7 +221,7 @@ get_caller_done:
        return ret;
 }
 
-int preload_threads_get_call_type(struct task_struct *task,
+int pt_get_call_type(struct task_struct *task,
                                  unsigned char *call_type)
 {
        struct thread_slot *slot;
@@ -243,7 +240,7 @@ get_call_type_done:
        return ret;
 }
 
-int preload_threads_get_drop(struct task_struct *task)
+int pt_get_drop(struct task_struct *task)
 {
        struct thread_slot *slot;
        int ret = 0;
@@ -261,8 +258,7 @@ get_drop_done:
        return ret;
 }
 
-bool preload_threads_check_disabled_probe(struct task_struct *task,
-                                         unsigned long addr)
+bool pt_check_disabled_probe(struct task_struct *task, unsigned long addr)
 {
        struct thread_slot *slot;
        bool ret = false;
@@ -274,7 +270,7 @@ bool preload_threads_check_disabled_probe(struct task_struct *task,
        return ret;
 }
 
-void preload_threads_enable_probe(struct task_struct *task, unsigned long addr)
+void pt_enable_probe(struct task_struct *task, unsigned long addr)
 {
        struct thread_slot *slot;
        struct disabled_addr *da;
@@ -293,7 +289,7 @@ enable_probe_failed:
        return; /* make gcc happy: cannot place label right before '}' */
 }
 
-int preload_threads_put_data(struct task_struct *task)
+int pt_put_data(struct task_struct *task)
 {
        struct thread_slot *slot;
        int ret = 0;
@@ -309,12 +305,12 @@ put_data_done:
        return ret;
 }
 
-int preload_threads_init(void)
+int pt_init(void)
 {
        return swap_ktd_reg(&preload_ktd);
 }
 
-void preload_threads_exit(void)
+void pt_exit(void)
 {
        swap_ktd_unreg(&preload_ktd);
 }
index a82c0e6..409320a 100644 (file)
@@ -1,24 +1,21 @@
-#ifndef __PRELOAD_THREADS_H__
-#define __PRELOAD_THREADS_H__
+#ifndef __PRELOAD_HANDLERS_THREADS_H__
+#define __PRELOAD_HANLDERS_THREADS_H__
 
 struct task_struct;
 
-unsigned long get_preload_flags(struct task_struct *task);
-void set_preload_flags(struct task_struct *task,
-                      unsigned long flags);
+unsigned long pt_get_flags(struct task_struct *task);
+void pt_set_flags(struct task_struct *task, unsigned long flags);
 
-int preload_threads_set_data(struct task_struct *task, unsigned long caller,
-                            unsigned char call_type,
-                            unsigned long disable_addr, bool drop);
-int preload_threads_get_caller(struct task_struct *task, unsigned long *caller);
-int preload_threads_get_call_type(struct task_struct *task,
-                                 unsigned char *call_type);
-int preload_threads_get_drop(struct task_struct *task);
-bool preload_threads_check_disabled_probe(struct task_struct *task,
-                                         unsigned long addr);
-void preload_threads_enable_probe(struct task_struct *task, unsigned long addr);
-int preload_threads_put_data(struct task_struct *task);
-int preload_threads_init(void);
-void preload_threads_exit(void);
+int pt_set_data(struct task_struct *task, unsigned long caller,
+                unsigned char call_type, unsigned long disable_addr,
+                bool drop);
+int pt_get_caller(struct task_struct *task, unsigned long *caller);
+int pt_get_call_type(struct task_struct *task, unsigned char *call_type);
+int pt_get_drop(struct task_struct *task);
+bool pt_check_disabled_probe(struct task_struct *task, unsigned long addr);
+void pt_enable_probe(struct task_struct *task, unsigned long addr);
+int pt_put_data(struct task_struct *task);
+int pt_init(void);
+void pt_exit(void);
 
-#endif /* __PRELOAD_THREADS_H__ */
+#endif /* __PRELOAD_HANDLERS_THREADS_H__ */