[IMPROVE] protorcol 4.0 35/38935/4
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 2 Mar 2015 11:28:19 +0000 (14:28 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 14 May 2015 11:45:06 +0000 (14:45 +0300)
Change-Id: I5e7e24cbcc04001f72b73f1e3eddb8949f9e0481
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
34 files changed:
driver/driver_to_buffer.c
ks_features/Kbuild
ks_features/features_data.c
ks_features/file_ops.c
ks_features/ks_features.c
ks_features/ksf_msg.c [new file with mode: 0644]
ks_features/ksf_msg.h [new file with mode: 0644]
parser/features.c
parser/msg_cmd.c
preload/preload_probe.c
retprobe/Kbuild
retprobe/retprobe.c
retprobe/rp_msg.c [new file with mode: 0644]
retprobe/rp_msg.h [new file with mode: 0644]
us_manager/Kbuild
us_manager/helper.c
us_manager/pf/pf_group.c
us_manager/sspt/sspt_proc.c
us_manager/us_manager.c
us_manager/usm_msg.c [new file with mode: 0644]
us_manager/usm_msg.h [new file with mode: 0644]
webprobe/Kbuild
webprobe/web_msg.c [new file with mode: 0644]
webprobe/web_msg.h [new file with mode: 0644]
webprobe/webprobe.c
writer/Kbuild
writer/debugfs_writer.c
writer/kernel_operations.h
writer/kernel_operations_arm.c [deleted file]
writer/kernel_operations_x86.c [deleted file]
writer/swap_msg.c [new file with mode: 0644]
writer/swap_msg.h [new file with mode: 0644]
writer/swap_writer_module.c
writer/swap_writer_module.h [deleted file]

index a24916e..7129c26 100644 (file)
@@ -37,7 +37,6 @@
 #include <buffer/swap_buffer_module.h>
 #include <buffer/swap_buffer_errors.h>
 #include <buffer/buffer_description.h>
-#include <writer/swap_writer_module.h>
 
 #include "driver_defs.h"
 #include "swap_driver_errors.h"
index a3dcfd7..207627d 100644 (file)
@@ -5,4 +5,5 @@ KBUILD_EXTRA_SYMBOLS = $(src)/../kprobe/Module.symvers \
 obj-m := swap_ks_features.o
 swap_ks_features-y := ks_features.o \
                       ks_map.o \
-                      file_ops.o
+                      file_ops.o \
+                      ksf_msg.o
index d12f7d7..3a96c80 100644 (file)
@@ -28,8 +28,9 @@
  */
 
 
+#include "ksf_msg.h"
 #include "syscall_list.h"
-#include <linux/mutex.h>
+
 
 /**
  * @struct feature
@@ -38,7 +39,7 @@
  * Syscalls count.
  * @var feature::feature_list
  * Pointer to feature's syscall list.
- * @var feature::sub_type
+ * @var feature::type
  * Featue subtype.
  * @var feature::enable
  * Is feature enable.
@@ -46,7 +47,7 @@
 struct feature {
        size_t cnt;
        enum syscall_id *feature_list;
-       int sub_type;
+       enum probe_t type;
 
        unsigned enable:1;
 };
@@ -285,22 +286,22 @@ static enum syscall_id id_desc[] = {
  * @def CREATE_FEATURE
  * Feature initialization.
  */
-#define CREATE_FEATURE(x, subtype)                             \
+#define CREATE_FEATURE(x, _type)                               \
 {                                                              \
        .cnt = sizeof(x) / sizeof(enum syscall_id),             \
        .feature_list = x,                                      \
-       .sub_type = subtype,                                    \
+       .type = _type,                                          \
        .enable = 0                                             \
 }
 
 static struct feature features[] = {
-       CREATE_FEATURE(id_none, PST_NONE),
-       CREATE_FEATURE(id_file, PST_KS_FILE),
-       CREATE_FEATURE(id_ipc, PST_KS_IPC),
-       CREATE_FEATURE(id_process, PST_KS_PROCESS),
-       CREATE_FEATURE(id_signal, PST_KS_SIGNAL),
-       CREATE_FEATURE(id_net, PST_KS_NETWORK),
-       CREATE_FEATURE(id_desc, PST_KS_DESC)
+       CREATE_FEATURE(id_none, PT_KS_NONE),
+       CREATE_FEATURE(id_file, PT_KS_FILE),
+       CREATE_FEATURE(id_ipc, PT_KS_IPC),
+       CREATE_FEATURE(id_process, PT_KS_PROCESS),
+       CREATE_FEATURE(id_signal, PT_KS_SIGNAL),
+       CREATE_FEATURE(id_net, PT_KS_NETWORK),
+       CREATE_FEATURE(id_desc, PT_KS_DESC)
 };
 
 /**
index 1a4b28c..0e00942 100644 (file)
@@ -9,8 +9,8 @@
 #include <linux/fs.h>
 #include <kprobe/swap_kprobes.h>
 #include <writer/event_filter.h>
-#include <writer/swap_writer_module.h>
 #include "ks_map.h"
+#include "ksf_msg.h"
 #include "file_ops.h"
 
 #define FOPS_PREFIX "[FILE_OPS] "
 /* path buffer size */
 enum { PATH_LEN = 512 };
 
-/* event subtypes: the same as for IO probes */
-enum {
-       FOPS_OPEN               = 0,
-       FOPS_CLOSE              = 1,
-       FOPS_READ_BEGIN         = 2,
-       FOPS_READ_END           = 3,
-       FOPS_READ               = FOPS_READ_BEGIN,
-       FOPS_WRITE_BEGIN        = 4,
-       FOPS_WRITE_END          = 5,
-       FOPS_WRITE              = FOPS_WRITE_BEGIN,
-       FOPS_DIRECTORY          = 6,
-       FOPS_PERMS              = 7,
-       FOPS_OTHER              = 8,
-       FOPS_SEND               = 9,
-       FOPS_RECV               = 10,
-       FOPS_OPTION             = 11,
-       FOPS_MANAGE             = 12,
-       FOPS_LOCK_START         = 14, /* 13 */
-       FOPS_LOCK_END           = 15,
-       FOPS_LOCK_RELEASE       = 16
-};
-
 struct file_probe {
        int id;
        const char *args;
@@ -394,10 +372,9 @@ static int generic_entry_handler(struct kretprobe_instance *ri,
                if (fops_fcheck(current, file) == 0) {
                        char *buf = fops_path_buf();
 
-                       custom_entry_event(F_ADDR(rp), regs, PT_FILE,
-                                          fprobe->subtype, "Sx",
-                                          fops_fpath(file, buf, PATH_LEN),
-                                          (u64)fd);
+                       ksf_msg_file_entry(fd, fprobe->subtype,
+                                          fops_fpath(file, buf, PATH_LEN));
+
                        priv->dentry = file->f_dentry;
                } else {
                        priv->dentry = NULL;
@@ -416,12 +393,8 @@ static int generic_ret_handler(struct kretprobe_instance *ri,
        struct kretprobe *rp = ri->rp;
        struct file_private *priv = (struct file_private *)ri->data;
 
-       if (rp && priv->dentry) {
-               struct file_probe *fprobe = to_file_probe(rp);
-
-               custom_exit_event(F_ADDR(rp), R_ADDR(ri), regs,
-                                 PT_FILE, fprobe->subtype, "x");
-       }
+       if (rp && priv->dentry)
+               ksf_msg_file_exit(regs, 'x');
 
        return 0;
 }
@@ -483,13 +456,11 @@ static int open_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 
                if (fops_fcheck(current, file) == 0) {
                        char *buf = fops_path_buf();
+                       const char *path = fops_fpath(file, buf, PATH_LEN);
 
-                       custom_entry_event(F_ADDR(rp), regs, PT_FILE,
-                                          fprobe->subtype, "Sxs",
-                                          fops_fpath(file, buf, PATH_LEN),
-                                          (u64)fd, priv->name);
-                       custom_exit_event(F_ADDR(rp), R_ADDR(ri), regs,
-                                         PT_FILE, fprobe->subtype, "x");
+                       ksf_msg_file_entry_open(fd, fprobe->subtype,
+                                               path, priv->name);
+                       ksf_msg_file_exit(regs, 'x');
                }
 
                if (file)
@@ -566,19 +537,14 @@ static int lock_entry_handler(struct kretprobe_instance *ri,
                        filepath = fops_fpath(file, buf, PATH_LEN);
 
                        if (lock_arg_init(fprobe->id, regs, &arg) == 0) {
-                               subtype = (arg.type == F_UNLCK ?
-                                          FOPS_LOCK_RELEASE :
-                                          FOPS_LOCK_START);
-
-                               custom_entry_event(F_ADDR(rp), regs, PT_FILE,
-                                                  subtype, "Sxddxx",
-                                                  filepath, (u64)fd,
-                                                  arg.type, arg.whence,
-                                                  arg.start, arg.len);
+                               subtype = arg.type == F_UNLCK ?
+                                               FOPS_LOCK_RELEASE :
+                                               FOPS_LOCK_START;
+                               ksf_msg_file_entry_lock(fd, subtype, filepath,
+                                                       arg.type, arg.whence,
+                                                       arg.start, arg.len);
                        } else {
-                               custom_entry_event(F_ADDR(rp), regs, PT_FILE,
-                                                  subtype, "Sx",
-                                                  filepath, (u64)fd);
+                               ksf_msg_file_entry(fd, subtype, filepath);
                        }
 
                        priv->dentry = file->f_dentry;
@@ -600,16 +566,8 @@ static int lock_ret_handler(struct kretprobe_instance *ri,
        struct kretprobe *rp = ri->rp;
        struct flock_private *priv = (struct flock_private *)ri->data;
 
-       if (rp && priv->dentry) {
-               int subtype;
-               if (priv->subtype == FOPS_LOCK_START)
-                       subtype = FOPS_LOCK_END;
-               else
-                       subtype = priv->subtype;
-
-               custom_exit_event(F_ADDR(rp), R_ADDR(ri), regs,
-                                 PT_FILE, subtype, "x");
-       }
+       if (rp && priv->dentry)
+               ksf_msg_file_exit(regs, 'x');
 
        return 0;
 }
index 59a22c1..5c4c0a0 100644 (file)
 #include <ksyms/ksyms.h>
 #include <kprobe/swap_kprobes.h>
 #include <master/swap_initializer.h>
-#include <writer/swap_writer_module.h>
 #include <writer/event_filter.h>
+#include "ksf_msg.h"
 #include "ks_features.h"
 #include "syscall_list.h"
 #include "features_data.c"
 #include "file_ops.h"
 
+
 /**
  * @struct ks_probe
  * @brief Kernel-space probe. Struct used as a container of syscall probes.
  * Installed probes counter.
  * @var ks_probe::args
  * Pointer to args format string.
- * @var ks_probe::sub_type
+ * @var ks_probe::type
  * Probe sub type.
  */
 struct ks_probe {
        struct kretprobe rp;
        int counter;
        char *args;
-       int sub_type;
+       int type;
 };
 
 #define CREATE_RP(name)                                                \
@@ -87,7 +88,7 @@ enum {
        .rp = CREATE_RP(name),                                  \
        .counter = 0,                                           \
        .args = #args__,                                        \
-       .sub_type = PST_NONE                                    \
+       .type = PT_KS_NONE                                      \
 }
 
 static struct ks_probe ksp[] = {
@@ -123,10 +124,10 @@ static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
        if (rp && check_event(current)) {
                struct ks_probe *ksp = container_of(rp, struct ks_probe, rp);
                const char *fmt = ksp->args;
-               unsigned long addr = (unsigned long)ksp->rp.kp.addr;
-               int sub_type = ksp->sub_type;
+               const unsigned long addr = (unsigned long)ksp->rp.kp.addr;
+               enum probe_t type = ksp->type;
 
-               entry_event(fmt, addr, regs, PT_KS, sub_type);
+               ksf_msg_entry(regs, addr, type, fmt);
        }
 
        return 0;
@@ -138,11 +139,11 @@ static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 
        if (rp && check_event(current)) {
                struct ks_probe *ksp = container_of(rp, struct ks_probe, rp);
-               unsigned long func_addr = (unsigned long)rp->kp.addr;
-               unsigned long ret_addr = (unsigned long)ri->ret_addr;
-               int sub_type = ksp->sub_type;
+               const unsigned long func_addr = (unsigned long)rp->kp.addr;
+               const unsigned long ret_addr = (unsigned long)ri->ret_addr;
+               enum probe_t type = ksp->type;
 
-               exit_event('x', regs, PT_KS, sub_type, func_addr, ret_addr);
+               ksf_msg_exit(regs, func_addr, ret_addr, type, 'x');
        }
 
        return 0;
@@ -157,7 +158,7 @@ static int switch_entry_handler(struct kretprobe_instance *ri,
                                struct pt_regs *regs)
 {
        if (check_event(current))
-               switch_entry(regs);
+               ksf_switch_entry(regs);
 
        return 0;
 }
@@ -166,7 +167,7 @@ static int switch_ret_handler(struct kretprobe_instance *ri,
                              struct pt_regs *regs)
 {
        if (check_event(current))
-               switch_exit(regs);
+               ksf_switch_exit(regs);
 
        return 0;
 }
@@ -326,12 +327,12 @@ static int unregister_multiple_syscalls(size_t *id_p, size_t cnt)
 
 static void set_pst(struct feature *f, size_t id)
 {
-       ksp[id].sub_type |= f->sub_type;
+       ksp[id].type |= f->type;
 }
 
 static void unset_pst(struct feature *f, size_t id)
 {
-       ksp[id].sub_type &= !f->sub_type;
+       ksp[id].type &= !f->type;
 }
 
 static void do_uninstall_features(struct feature *f, size_t i)
diff --git a/ks_features/ksf_msg.c b/ks_features/ksf_msg.c
new file mode 100644 (file)
index 0000000..100fe85
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2015
+ *
+ * 2015         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ */
+
+
+#include <linux/sched.h>
+#include <writer/swap_msg.h>
+#include <writer/kernel_operations.h>
+#include "ksf_msg.h"
+
+
+#define KSF_PREFIX     KERN_INFO "[KSF] "
+
+
+
+
+
+/* ============================================================================
+ * =                       MSG_SYSCALL_* (ENTRY/EXIT)                         =
+ * ============================================================================
+ */
+struct msg_sys_header {
+       u32 pid;
+       u32 tid;
+       u32 probe_type;
+       u64 pc_addr;
+       u64 caller_pc_addr;
+       u32 cpu_num;
+} __packed;
+
+struct msg_sys_entry {
+       struct msg_sys_header h;
+       u32 cnt_args;
+       char args[0];
+} __packed;
+
+struct msg_sys_exit {
+       struct msg_sys_header h;
+       char ret_val[0];
+} __packed;
+
+
+static void pack_header(struct msg_sys_header *h, unsigned long func_addr,
+                       unsigned long ret_addr, enum probe_t type)
+{
+       struct task_struct *task = current;
+
+       h->pid = task->tgid;
+       h->tid = task->pid;
+       h->probe_type = (u32)type;
+       h->pc_addr = func_addr;
+       h->caller_pc_addr = ret_addr;
+       h->cpu_num = smp_processor_id();
+}
+
+static void pack_entry_header(struct msg_sys_entry *e, struct pt_regs *regs,
+                             unsigned long func_addr, enum probe_t type,
+                             const char *fmt)
+{
+       pack_header(&e->h, func_addr, get_regs_ret_func(regs), type);
+       e->cnt_args = strlen(fmt);
+}
+
+static void pack_exit_header(struct msg_sys_exit *e, unsigned long func_addr,
+                            unsigned long ret_addr, enum probe_t type)
+{
+       pack_header(&e->h, func_addr, ret_addr, type);
+}
+
+void ksf_msg_entry(struct pt_regs *regs, unsigned long func_addr,
+                  enum probe_t type, const char *fmt)
+{
+       int ret;
+       struct swap_msg *m;
+       struct msg_sys_entry *ent;
+       size_t size;
+
+       m = swap_msg_get(MSG_SYSCALL_ENTRY);
+
+       ent = swap_msg_payload(m);
+       pack_entry_header(ent, regs, func_addr, type, fmt);
+
+       size = swap_msg_size(m) - sizeof(*ent);
+       ret = swap_msg_pack_args(ent->args, size, fmt, regs);
+       if (ret < 0) {
+               printk(KSF_PREFIX "ERROR: arguments packing, ret=%d\n", ret);
+               goto put_msg;
+       }
+
+       swap_msg_flush(m, sizeof(*ent) + ret);
+
+put_msg:
+       swap_msg_put(m);
+}
+
+void ksf_msg_exit(struct pt_regs *regs, unsigned long func_addr,
+                 unsigned long ret_addr, enum probe_t type, char ret_type)
+{
+       int ret;
+       struct swap_msg *m;
+       struct msg_sys_exit *ext;
+       size_t size;
+
+       m = swap_msg_get(MSG_SYSCALL_EXIT);
+
+       ext = swap_msg_payload(m);
+       pack_exit_header(ext, func_addr, ret_addr, type);
+
+       size = swap_msg_size(m) - sizeof(*ext);
+       ret = swap_msg_pack_ret_val(ext->ret_val, size, ret_type, regs);
+       if (ret < 0) {
+               printk(KSF_PREFIX "ERROR: ret value packing, ret=%d\n", ret);
+               goto put_msg;
+       }
+
+       swap_msg_flush(m, sizeof(*ext) + ret);
+
+put_msg:
+       swap_msg_put(m);
+}
+
+
+
+
+
+/* ============================================================================
+ * =                    MSG_FILE_FUNCTION_* (ENTRY/EXIT)                      =
+ * ============================================================================
+ */
+struct msg_file_entry {
+       u32 pid;
+       u32 tid;
+       u32 fd;
+       u32 event_type;
+       char file_path[0];
+} __packed;
+
+enum file_info {
+       FI_GENIRAL = 0,
+       FI_OPEN = 1,
+       FI_LOCK = 2
+};
+
+static int pack_file_entry_head(void *data, size_t size, enum file_info info,
+                               int fd, enum file_api_t api, const char *path)
+{
+       struct msg_file_entry *ent = (struct msg_file_entry *)data;
+       struct task_struct *task = current;
+       size_t len, old_size = size;
+
+       ent->pid = task->tgid;
+       ent->tid = task->pid;
+       ent->fd = fd;
+       ent->event_type = api;
+
+       size -= sizeof(*ent);
+       len = strlen(path);
+       if (size < len + 1)
+               return -ENOMEM;
+
+       memcpy(ent->file_path, path, len);
+       ent->file_path[len] = '\0';
+
+       size -= len + 1;
+       data += old_size - size;
+
+       if (size < 4)
+               return -ENOMEM;
+
+       *((u32 *)data) = (u32)info;
+       size -= 4;
+
+       return old_size - size;
+}
+
+
+
+void ksf_msg_file_entry(int fd, enum file_api_t api, const char *path)
+{
+       int ret;
+       void *p;
+       size_t size;
+       struct swap_msg *m;
+
+       m = swap_msg_get(MSG_FILE_FUNCTION_ENTRY);
+       p = swap_msg_payload(m);
+       size = swap_msg_size(m);
+
+       ret = pack_file_entry_head(p, size, FI_GENIRAL, fd, api, path);
+       if (ret < 0) {
+               printk(KSF_PREFIX "buffer is too small\n");
+               goto put_msg;
+       }
+
+       swap_msg_flush(m, ret);
+
+put_msg:
+       swap_msg_put(m);
+}
+
+void ksf_msg_file_entry_open(int fd, enum file_api_t api, const char *path,
+                            const char __user *ofile)
+{
+       long n;
+       int ret;
+       void *p;
+       size_t size;
+       struct swap_msg *m;
+
+       m = swap_msg_get(MSG_FILE_FUNCTION_ENTRY);
+       p = swap_msg_payload(m);
+       size = swap_msg_size(m);
+
+       ret = pack_file_entry_head(p, size, FI_OPEN, fd, api, path);
+       if (ret < 0) {
+               printk(KSF_PREFIX "buffer is too small\n");
+               goto put_msg;
+       }
+
+       size -= ret;
+       p += ret;
+
+       n = strncpy_from_user(p, ofile, size);
+       if (n < 0) {
+               printk(KSF_PREFIX "cannot copy ofile\n");
+               swap_msg_put(m);
+       }
+
+       swap_msg_flush(m, ret + n + 1);
+
+put_msg:
+       swap_msg_put(m);
+}
+
+struct lock_arg {
+       u32 type;
+       u32 whence;
+       u64 start;
+       u64 len;
+} __packed;
+
+void ksf_msg_file_entry_lock(int fd, enum file_api_t api, const char *path,
+                            int type, int whence, s64 start, s64 len)
+{
+       int ret;
+       void *p;
+       size_t size;
+       struct swap_msg *m;
+       struct lock_arg *arg;
+
+       m = swap_msg_get(MSG_FILE_FUNCTION_ENTRY);
+       p = swap_msg_payload(m);
+       size = swap_msg_size(m);
+
+       ret = pack_file_entry_head(p, size, FI_LOCK, fd, api, path);
+       if (ret < 0) {
+               printk(KSF_PREFIX "buffer is too small\n");
+               goto put_msg;
+       }
+
+       size -= ret;
+       p += ret;
+
+       if (size < sizeof(*arg)) {
+               printk(KSF_PREFIX "buffer is too small\n");
+               goto put_msg;
+       }
+
+       arg = (struct lock_arg *)p;
+       arg->type = (u32)type;
+       arg->whence = (u32)whence;
+       arg->start = (u64)start;
+       arg->len = (u64)len;
+
+       swap_msg_flush(m, ret + sizeof(*arg));
+
+put_msg:
+       swap_msg_put(m);
+}
+
+
+struct msg_file_exit {
+       u32 pid;
+       u32 tid;
+       char ret_val[0];
+} __packed;
+
+void ksf_msg_file_exit(struct pt_regs *regs, char ret_type)
+{
+       struct task_struct *task = current;
+       int ret;
+       struct swap_msg *m;
+       struct msg_file_exit *ext;
+       size_t size;
+
+       m = swap_msg_get(MSG_FILE_FUNCTION_EXIT);
+
+       ext = swap_msg_payload(m);
+       ext->pid = task->tgid;
+       ext->tid = task->pid;
+
+       size = swap_msg_size(m) - sizeof(*ext);
+       ret = swap_msg_pack_ret_val(ext->ret_val, size, ret_type, regs);
+       if (ret < 0) {
+               printk(KSF_PREFIX "ERROR: ret value packing, ret=%d\n", ret);
+               goto put_msg;
+       }
+
+       swap_msg_flush(m, sizeof(*ext) + ret);
+
+put_msg:
+       swap_msg_put(m);
+}
+
+
+
+
+
+/* ============================================================================
+ * =                    MSG_FILE_FUNCTION_* (ENTRY/EXIT)                      =
+ * ============================================================================
+ */
+struct msg_context_switch {
+       u64 pc_addr;
+       u32 pid;
+       u32 tid;
+       u32 cpu_num;
+} __packed;
+
+static void context_switch(struct pt_regs *regs, enum swap_msg_id id)
+{
+       struct task_struct *task = current;
+       struct swap_msg *m;
+       struct msg_context_switch *mcs;
+       void *p;
+
+       m = swap_msg_get(id);
+       p = swap_msg_payload(m);
+
+       mcs = p;
+       mcs->pc_addr = 0;
+       mcs->pid = task->tgid;
+       mcs->tid = task->pid;
+       mcs->cpu_num = smp_processor_id();
+
+       swap_msg_flush(m, sizeof(*mcs));
+       swap_msg_put(m);
+}
+
+void ksf_switch_entry(struct pt_regs *regs)
+{
+       context_switch(regs, MSG_CONTEXT_SWITCH_ENTRY);
+}
+
+void ksf_switch_exit(struct pt_regs *regs)
+{
+       context_switch(regs, MSG_CONTEXT_SWITCH_EXIT);
+}
diff --git a/ks_features/ksf_msg.h b/ks_features/ksf_msg.h
new file mode 100644 (file)
index 0000000..6be8d5e
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2015
+ *
+ * 2015         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ */
+
+
+#ifndef _KSF_MSG_H
+#define _KSF_MSG_H
+
+
+enum probe_t {
+       PT_KS_NONE      = 0x00,
+       PT_KS_FILE      = 0x01,
+       PT_KS_IPC       = 0x02,
+       PT_KS_PROCESS   = 0x04,
+       PT_KS_SIGNAL    = 0x08,
+       PT_KS_NETWORK   = 0x10,
+       PT_KS_DESC      = 0x20
+};
+
+
+enum file_api_t {
+       FOPS_OPEN               = 0,
+       FOPS_CLOSE              = 1,
+       FOPS_READ_BEGIN         = 2,
+       FOPS_READ_END           = 3,
+       FOPS_READ               = FOPS_READ_BEGIN,
+       FOPS_WRITE_BEGIN        = 4,
+       FOPS_WRITE_END          = 5,
+       FOPS_WRITE              = FOPS_WRITE_BEGIN,
+       FOPS_DIRECTORY          = 6,
+       FOPS_PERMS              = 7,
+       FOPS_OTHER              = 8,
+       FOPS_SEND               = 9,
+       FOPS_RECV               = 10,
+       FOPS_OPTION             = 11,
+       FOPS_MANAGE             = 12,
+       FOPS_LOCK_START         = 14, /* 13 */
+       FOPS_LOCK_END           = 15,
+       FOPS_LOCK_RELEASE       = 16
+};
+
+
+struct pt_regs;
+
+
+void ksf_msg_entry(struct pt_regs *regs, unsigned long func_addr,
+                  enum probe_t type, const char *fmt);
+void ksf_msg_exit(struct pt_regs *regs, unsigned long func_addr,
+                 unsigned long ret_addr, enum probe_t type, char ret_type);
+
+void ksf_msg_file_entry(int fd, enum file_api_t api, const char *path);
+void ksf_msg_file_entry_open(int fd, enum file_api_t api, const char *path,
+                            const char __user *ofile);
+void ksf_msg_file_entry_lock(int fd, enum file_api_t api, const char *path,
+                            int type, int whence, s64 start, s64 len);
+void ksf_msg_file_exit(struct pt_regs *regs, char ret_type);
+
+void ksf_switch_entry(struct pt_regs *regs);
+void ksf_switch_exit(struct pt_regs *regs);
+
+
+#endif /* _KSF_MSG_H */
index 2e7495b..beb7f6b 100644 (file)
@@ -29,6 +29,7 @@
 
 
 #include <linux/types.h>
+#include <linux/sched.h>
 #include <linux/module.h>
 #include <ks_features/ks_features.h>
 #include <us_manager/us_manager.h>
@@ -36,8 +37,8 @@
 #include "features.h"
 #include "msg_parser.h"
 
+#include <writer/swap_msg.h>
 #include <writer/event_filter.h>
-#include <writer/swap_writer_module.h>
 #include <sampler/swap_sampler_module.h>
 #include <energy/energy.h>
 
@@ -284,6 +285,34 @@ int unset_context_switch(void)
 }
 
 
+
+
+
+struct sample {
+       u32 pid;
+       u64 pc_addr;
+       u32 tid;
+       u32 cpu_num;
+} __packed;
+
+static void sample_msg(struct pt_regs *regs)
+{
+       struct swap_msg *m;
+       struct sample *s;
+       struct task_struct *task = current;
+
+       m = swap_msg_get(MSG_SAMPLE);
+
+       s = swap_msg_payload(m);
+       s->pid = task->tgid;
+       s->pc_addr = instruction_pointer(regs);
+       s->tid = task->pid;
+       s->cpu_num = smp_processor_id();
+
+       swap_msg_flush(m, sizeof(*s));
+       swap_msg_put(m);
+}
+
 static void sampler_cb(struct pt_regs *regs)
 {
        if (check_event(current))
index 1da2341..5d6f01c 100644 (file)
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/module.h>
-#include <writer/swap_writer_module.h>
 #include "msg_parser.h"
 #include "msg_buf.h"
 #include "features.h"
 #include "parser_defs.h"
 #include "us_inst.h"
+#include <writer/swap_msg.h>
 #include <us_manager/us_manager.h>
 
+
 static int wrt_launcher_port;
 
 static int set_config(struct conf_data *conf)
@@ -78,8 +79,8 @@ int msg_start(struct msg_buf *mb)
        struct us_inst_data *us_inst;
        struct conf_data conf;
 
-       reset_seq_num();
-       reset_discarded();
+       swap_msg_seq_num_reset();
+       swap_msg_discard_reset();
 
        us_inst = create_us_inst_data(mb);
        if (us_inst == NULL)
@@ -121,7 +122,7 @@ int msg_stop(struct msg_buf *mb)
 {
        int ret = 0;
        struct conf_data conf;
-       unsigned int discarded;
+       int discarded;
 
        if (!is_end_mb(mb)) {
                print_err("to long message, remained=%u", remained_mb(mb));
@@ -138,9 +139,9 @@ int msg_stop(struct msg_buf *mb)
        if (ret)
                printk(KERN_INFO "Cannot set config, ret = %d\n", ret);
 
-       discarded = get_discarded_count();
+       discarded = swap_msg_discard_get();
        printk(KERN_INFO "discarded messages: %d\n", discarded);
-       reset_discarded();
+       swap_msg_discard_reset();
 
        return ret;
 }
index d773251..efb0d29 100644 (file)
@@ -26,7 +26,6 @@
 #include <us_manager/us_manager.h>
 #include <us_manager/probes/register_probes.h>
 #include <us_manager/sspt/sspt_page.h>
-#include <writer/swap_writer_module.h>
 #include <uprobe/swap_uprobes.h>
 #include <us_manager/sspt/ip.h>
 #include "preload_probe.h"
index 0c9fefb..c61030c 100644 (file)
@@ -1,4 +1,6 @@
 EXTRA_CFLAGS := $(extra_cflags)
 
 obj-m := swap_retprobe.o
-swap_retprobe-y := retprobe.o
+swap_retprobe-y := \
+    retprobe.o \
+    rp_msg.o
index 96ba8c4..5a29986 100644 (file)
 #include <us_manager/us_manager.h>
 #include <us_manager/sspt/ip.h>
 #include <us_manager/probes/register_probes.h>
-#include <writer/swap_writer_module.h>
 #include <uprobe/swap_uprobes.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include "rp_msg.h"
+
 
 static int retprobe_copy(struct probe_info *dest,
                         const struct probe_info *source)
@@ -78,9 +79,9 @@ static int retprobe_entry_handler(struct uretprobe_instance *ri, struct pt_regs
        if (rp && get_quiet() == QT_OFF) {
                struct us_ip *ip = container_of(rp, struct us_ip, retprobe);
                const char *fmt = ip->probe_i.rp_i.args;
-               unsigned long addr = (unsigned long)ip->orig_addr;
+               const unsigned long func_addr = (unsigned long)ip->orig_addr;
 
-               entry_event(fmt, addr, regs, PT_US, PST_NONE);
+               rp_msg_entry(regs, func_addr, fmt);
        }
 
        return 0;
@@ -92,11 +93,11 @@ static int retprobe_ret_handler(struct uretprobe_instance *ri, struct pt_regs *r
 
        if (rp && get_quiet() == QT_OFF) {
                struct us_ip *ip = container_of(rp, struct us_ip, retprobe);
-               unsigned long addr = (unsigned long)ip->orig_addr;
-               unsigned long ret_addr = (unsigned long)ri->ret_addr;
+               const unsigned long func_addr = (unsigned long)ip->orig_addr;
+               const unsigned long ret_addr = (unsigned long)ri->ret_addr;
+               const char ret_type = ip->probe_i.rp_i.ret_type;
 
-               exit_event(ip->probe_i.rp_i.ret_type, regs, PT_US, PST_NONE, addr,
-                  ret_addr);
+               rp_msg_exit(regs, func_addr, ret_type, ret_addr);
        }
 
        return 0;
diff --git a/retprobe/rp_msg.c b/retprobe/rp_msg.c
new file mode 100644 (file)
index 0000000..32b9771
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2015
+ *
+ * 2015         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ */
+
+
+#include <linux/sched.h>
+#include <writer/swap_msg.h>
+#include <writer/kernel_operations.h>
+#include "rp_msg.h"
+
+
+#define RP_PREFIX      KERN_INFO "[RP] "
+
+
+struct msg_entry {
+       u32 pid;
+       u32 tid;
+       u64 pc_addr;
+       u64 caller_pc_addr;
+       u32 cpu_num;
+       u32 cnt_args;
+       char args[0];
+} __packed;
+
+struct msg_exit {
+       u32 pid;
+       u32 tid;
+       u64 pc_addr;
+       u64 caller_pc_addr;
+       u32 cpu_num;
+       char ret_val[0];
+} __packed;
+
+
+void rp_msg_entry(struct pt_regs *regs, unsigned long func_addr,
+                 const char *fmt)
+{
+       int ret;
+       struct task_struct *task = current;
+       struct swap_msg *m;
+       struct msg_entry *ent;
+       void *p;
+       size_t size;
+
+       m = swap_msg_get(MSG_FUNCTION_ENTRY);
+       p = swap_msg_payload(m);
+
+       ent = p;
+       ent->pid = task->tgid;
+       ent->tid = task->pid;
+       ent->pc_addr = func_addr;
+       ent->caller_pc_addr = get_regs_ret_func(regs);
+       ent->cpu_num = smp_processor_id();
+       ent->cnt_args = strlen(fmt);
+
+       size = swap_msg_size(m);
+       ret = swap_msg_pack_args(p + sizeof(*ent), size - sizeof(*ent),
+                                fmt, regs);
+       if (ret < 0) {
+               printk(RP_PREFIX "ERROR: arguments packing, ret=%d\n", ret);
+               goto put_msg;
+       }
+
+       swap_msg_flush(m, sizeof(*ent) + ret);
+
+put_msg:
+       swap_msg_put(m);
+}
+
+void rp_msg_exit(struct pt_regs *regs, unsigned long func_addr,
+                char ret_type, unsigned long ret_addr)
+{
+       int ret;
+       struct task_struct *task = current;
+       struct swap_msg *m;
+       struct msg_exit *ext;
+       void *p;
+       size_t size;
+
+       m = swap_msg_get(MSG_FUNCTION_EXIT);
+       p = swap_msg_payload(m);
+
+       ext = p;
+       ext->pid = task->tgid;
+       ext->tid = task->pid;
+       ext->pc_addr = func_addr;
+       ext->caller_pc_addr = ret_addr;
+       ext->cpu_num = smp_processor_id();
+
+       size = swap_msg_size(m);
+       ret = swap_msg_pack_ret_val(p + sizeof(*ext), size - sizeof(*ext),
+                                   ret_type, regs);
+       if (ret < 0) {
+               printk(RP_PREFIX "ERROR: return value packing, ret=%d\n", ret);
+               goto put_msg;
+       }
+
+       swap_msg_flush(m, sizeof(*ext) + ret);
+
+put_msg:
+       swap_msg_put(m);
+}
diff --git a/retprobe/rp_msg.h b/retprobe/rp_msg.h
new file mode 100644 (file)
index 0000000..a2e3b28
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2015
+ *
+ * 2015         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ */
+
+
+#ifndef _RP_MSG_H
+#define _RP_MSG_H
+
+
+struct pt_regs;
+
+
+void rp_msg_entry(struct pt_regs *regs, unsigned long func_addr,
+                 const char *fmt);
+void rp_msg_exit(struct pt_regs *regs, unsigned long func_addr,
+                char ret_type, unsigned long ret_addr);
+
+
+#endif /* _RP_MSG_H */
index c6db3e9..6481da5 100644 (file)
@@ -9,4 +9,5 @@ swap_us_manager-y := us_manager.o us_slot_manager.o helper.o debugfs_us_manager.
                      sspt/sspt_feature.o sspt/sspt_filter.o \
                      pf/proc_filters.o pf/pf_group.o \
                      img/img_proc.o img/img_file.o img/img_ip.o \
-                     probes/probes.o
+                     probes/probes.o \
+                     usm_msg.o
index cca5b09..7a5bc37 100644 (file)
@@ -27,9 +27,9 @@
 #include <kprobe/swap_kprobes_deps.h>
 #include <ksyms/ksyms.h>
 #include <writer/kernel_operations.h>
-#include <writer/swap_writer_module.h>
 #include "us_slot_manager.h"
 #include "sspt/sspt.h"
+#include "usm_msg.h"
 #include "helper.h"
 
 struct task_struct;
@@ -343,7 +343,7 @@ static void __remove_unmap_probes(struct sspt_proc *proc,
 
                sspt_proc_insert_files(proc, &head);
 
-               proc_unmap_msg(start, end);
+               usm_msg_unmap(start, end);
        }
 }
 
@@ -384,8 +384,7 @@ static int ret_handler_unmap(struct kretprobe_instance *ri,
        struct task_struct *task;
 
        task = current->group_leader;
-       if (is_kthread(task) ||
-           get_regs_ret_val(regs))
+       if (is_kthread(task) || regs_return_value(regs))
                goto out;
 
        remove_unmap_probes(task, (struct unmap_data *)ri->data);
@@ -444,7 +443,7 @@ static int ret_handler_mmap(struct kretprobe_instance *ri,
        if (is_kthread(task))
                return 0;
 
-       start_addr = (unsigned long)get_regs_ret_val(regs);
+       start_addr = regs_return_value(regs);
        if (IS_ERR_VALUE(start_addr))
                return 0;
 
@@ -454,7 +453,7 @@ static int ret_handler_mmap(struct kretprobe_instance *ri,
 
        vma = find_vma_intersection(task->mm, start_addr, start_addr + 1);
        if (vma && check_vma(vma))
-               pcoc_map_msg(vma);
+               usm_msg_map(vma);
 
        return 0;
 }
index 8a5b334..c19242c 100644 (file)
 #include <linux/slab.h>
 #include <linux/list.h>
 #include "proc_filters.h"
+#include <us_manager/usm_msg.h>
 #include <us_manager/img/img_proc.h>
 #include <us_manager/img/img_file.h>
 #include <us_manager/img/img_ip.h>
 #include <us_manager/sspt/sspt_proc.h>
 #include <us_manager/helper.h>
-#include <writer/swap_writer_module.h>
 
 struct pf_group {
        struct list_head list;
@@ -190,7 +190,7 @@ static void first_install(struct task_struct *task, struct sspt_proc *proc,
        }
 
        down_write(&task->mm->mmap_sem);
-       proc_info_msg(task, dentry);
+       usm_msg_info(task, dentry);
        sspt_proc_install(proc);
        up_write(&task->mm->mmap_sem);
 }
index 8de9368..cde887e 100644 (file)
@@ -30,8 +30,8 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/list.h>
+#include <us_manager/usm_msg.h>
 #include <us_manager/us_slot_manager.h>
-#include <writer/swap_writer_module.h>
 
 
 static LIST_HEAD(proc_probes_list);
@@ -135,7 +135,7 @@ void sspt_proc_free(struct sspt_proc *proc)
 
        sspt_destroy_feature(proc->feature);
 
-       terminate_msg(proc->task);
+       usm_msg_term(proc->task);
        free_sm_us(proc->sm);
        kfree(proc);
 }
index fb0ee5e..57f3c26 100644 (file)
 #include "helper.h"
 #include "us_manager.h"
 #include "debugfs_us_manager.h"
-
 #include <writer/event_filter.h>
 #include <master/swap_initializer.h>
 
-/* FIXME: move /un/init_msg() elsewhere and remove this include  */
-#include <writer/swap_writer_module.h>         /* for /un/init_msg() */
-
-
 
 static DEFINE_MUTEX(mutex_inst);
 static enum status_type status = ST_OFF;
@@ -215,12 +210,6 @@ static int init_us_manager(void)
        int ret;
 
        ret = init_us_filter();
-       if (ret)
-               return ret;
-
-       ret = init_msg(32*1024); /* TODO: move to writer */
-       if (ret)
-               exit_us_filter();
 
        return ret;
 }
@@ -230,7 +219,6 @@ static void exit_us_manager(void)
        if (status == ST_ON)
                do_usm_stop();
 
-       uninit_msg();
        exit_us_filter();
 }
 
diff --git a/us_manager/usm_msg.c b/us_manager/usm_msg.c
new file mode 100644 (file)
index 0000000..a81c0ec
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2015
+ *
+ * 2015         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ */
+
+
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/dcache.h>
+
+#include <writer/swap_msg.h>
+#include <us_manager/sspt/sspt.h>      /* ... check_vma() */
+
+
+#define USM_PREFIX      KERN_INFO "[USM] "
+
+
+struct kmem_info {
+       const char *name;
+       unsigned long start;
+       unsigned long end;
+};
+
+static void kmem_info_fill(struct kmem_info *info, struct mm_struct *mm)
+{
+#if defined(CONFIG_ARM)
+       info->name = "[vectors]"
+       info->start = CONFIG_VECTORS_BASE;
+       info->end = CONFIG_VECTORS_BASE + PAGE_SIZE;
+#elif defined(CONFIG_X86_32)
+       unsigned long vdso;
+       struct vm_area_struct *vma_vdso;
+
+       vdso = (unsigned long)mm->context.vdso;
+       vma_vdso = find_vma_intersection(mm, vdso, vdso + 1);
+       if (vma_vdso) {
+               info->name = "[vdso]";
+               info->start = vma_vdso->vm_start;
+               info->end = vma_vdso->vm_end;
+       } else {
+               printk(USM_PREFIX "Cannot get VDSO mapping\n");
+
+               info->name = NULL;
+               info->start = 0;
+               info->end = 0;
+       }
+#endif /* CONFIG_arch */
+}
+
+
+static int pack_path(void *data, size_t size, struct file *file)
+{
+       enum { TMP_BUF_LEN = 512 };
+       char tmp_buf[TMP_BUF_LEN];
+       const char NA[] = "N/A";
+       const char *filename;
+       size_t len = sizeof(NA);
+
+       if (file == NULL) {
+               filename = NA;
+               goto cp2buf;
+       }
+
+       filename = d_path(&file->f_path, tmp_buf, TMP_BUF_LEN);
+       if (IS_ERR_OR_NULL(filename)) {
+               filename = NA;
+               goto cp2buf;
+       }
+
+       len = strlen(filename) + 1;
+
+cp2buf:
+       if (size < len)
+               return -ENOMEM;
+
+       memcpy(data, filename, len);
+       return len;
+}
+
+
+
+
+
+/* ============================================================================
+ * =                             MSG_PROCESS_INFO                             =
+ * ============================================================================
+ */
+struct proc_info_top {
+       u32 pid;
+       char comm[0];
+} __packed;
+
+struct proc_info_bottom {
+       u32 ppid;
+       u64 start_time;
+       u64 low_addr;
+       u64 high_addr;
+       char bin_path[0];
+} __packed;
+
+struct lib_obj {
+       u64 low_addr;
+       u64 high_addr;
+       char lib_path[0];
+} __packed;
+
+static int pack_lib_obj(void *data, size_t size, struct vm_area_struct *vma)
+{
+       int ret;
+       struct lib_obj *obj = (struct lib_obj *)data;
+
+       if (size < sizeof(*obj))
+               return -ENOMEM;
+
+       obj->low_addr = vma->vm_start;
+       obj->high_addr = vma->vm_end;
+       size -= sizeof(*obj);
+
+       ret = pack_path(obj->lib_path, size, vma->vm_file);
+       if (ret < 0)
+               return ret;
+
+       return ret + sizeof(*obj);
+}
+
+static int pack_shared_kmem(void *data, size_t size, struct mm_struct *mm)
+{
+       struct lib_obj *obj = (struct lib_obj *)data;
+       struct kmem_info info;
+       size_t name_len, obj_size;
+
+       if (size < sizeof(*obj))
+               return -ENOMEM;
+
+       kmem_info_fill(&info, mm);
+
+       if (info.name == NULL)
+               return 0;
+
+       obj->low_addr = (u64)info.start;
+       obj->high_addr = (u64)info.end;
+
+       name_len = strlen(info.name) + 1;
+       obj_size = sizeof(*obj) + name_len;
+       if (size < obj_size)
+               return -ENOMEM;
+
+       memcpy(obj->lib_path, info.name, name_len);
+
+       return obj_size;
+}
+
+static int pack_libs(void *data, size_t size, struct mm_struct *mm)
+{
+       int ret;
+       struct vm_area_struct *vma;
+       u32 *lib_cnt = (u32 *)data;
+       const size_t old_size = size;
+
+       if (size < sizeof(*lib_cnt))
+               return -ENOMEM;
+
+       /* packing libraries count */
+       *lib_cnt = 0;
+       data += sizeof(*lib_cnt);
+       size -= sizeof(*lib_cnt);
+
+       /* packing libraries */
+       for (vma = mm->mmap; vma; vma = vma->vm_next) {
+               if (check_vma(vma)) {
+                       ret = pack_lib_obj(data, size, vma);
+                       if (ret < 0)
+                               return ret;
+
+                       data += ret;
+                       size -= ret;
+                       ++(*lib_cnt);
+               }
+       }
+
+       /* packing shared kernel memory */
+       ret = pack_shared_kmem(data, size, mm);
+       if (ret < 0)
+               return ret;
+
+       *lib_cnt += !!ret;
+       size -= ret;
+
+       return old_size - size;
+}
+
+static struct vm_area_struct *find_vma_exe_by_dentry(struct mm_struct *mm,
+                                                    struct dentry *dentry)
+{
+       struct vm_area_struct *vma;
+
+       for (vma = mm->mmap; vma; vma = vma->vm_next) {
+               if (vma->vm_file && (vma->vm_flags & VM_EXEC) &&
+                  (vma->vm_file->f_dentry == dentry))
+                       goto out;
+       }
+
+       vma = NULL;
+out:
+
+       return vma;
+}
+
+static int pack_proc_info_top(void *data, size_t size,
+                             struct task_struct *task)
+{
+       struct proc_info_top *pit = (struct proc_info_top *)data;
+
+       if (size < sizeof(*pit) + sizeof(task->comm))
+               return -ENOMEM;
+
+       pit->pid = task->tgid;
+       get_task_comm(pit->comm, task);
+
+       return sizeof(*pit) + strlen(pit->comm) + 1;
+}
+
+static int pack_proc_info_bottom(void *data, size_t size,
+                                struct task_struct *task,
+                                struct dentry *dentry)
+{
+       struct proc_info_bottom *pib = (struct proc_info_bottom *)data;
+       struct vm_area_struct *vma = find_vma_exe_by_dentry(task->mm, dentry);
+       struct timespec boot_time;
+       struct timespec start_time;
+       int ret;
+
+       if (size < sizeof(*pib))
+               return -ENOMEM;
+
+       getboottime(&boot_time);
+       start_time = timespec_add(boot_time, task->real_start_time);
+
+       pib->ppid = task->real_parent->tgid;
+       pib->start_time = swap_msg_spec2time(&start_time);
+
+       if (vma) {
+               pib->low_addr = vma->vm_start;
+               pib->high_addr = vma->vm_end;
+               ret = pack_path(pib->bin_path, size, vma->vm_file);
+       } else {
+               pib->low_addr = 0;
+               pib->high_addr = 0;
+               ret = pack_path(pib->bin_path, size, NULL);
+       }
+
+       if (ret < 0)
+               return ret;
+
+       return sizeof(*pib) + ret;
+}
+
+static int pack_proc_info(void *data, size_t size, struct task_struct *task,
+                           struct dentry *dentry)
+{
+       int ret;
+       const size_t old_size = size;
+
+       ret = pack_proc_info_top(data, size, task);
+       if (ret < 0)
+               return ret;
+
+       data += ret;
+       size -= ret;
+
+       ret = pack_proc_info_bottom(data, size, task, dentry);
+       if (ret < 0)
+               return ret;
+
+       data += ret;
+       size -= ret;
+
+       ret = pack_libs(data, size, task->mm);
+       if (ret < 0)
+               return ret;
+
+       return old_size - size + ret;
+}
+
+/* Called with down\up\_read(&task->mm->mmap_sem). */
+void usm_msg_info(struct task_struct *task, struct dentry *dentry)
+{
+       int ret;
+       struct swap_msg *m;
+       void *p;
+       size_t size;
+
+       m = swap_msg_get(MSG_PROC_INFO);
+       p = swap_msg_payload(m);
+       size = swap_msg_size(m);
+
+       ret = pack_proc_info(p, size, task, dentry);
+       if (ret < 0) {
+               printk(USM_PREFIX "ERROR: message process info packing, "
+                      "ret=%d\n", ret);
+               goto put_msg;
+       }
+
+       swap_msg_flush(m, ret);
+
+put_msg:
+       swap_msg_put(m);
+}
+
+
+
+
+
+/* ============================================================================
+ * =                              MSG_TERMINATE                               =
+ * ============================================================================
+ */
+struct proc_terminate {
+       u32 pid;
+} __packed;
+
+void usm_msg_term(struct task_struct *task)
+{
+       struct swap_msg *m;
+       struct proc_terminate *term;
+
+       m = swap_msg_get(MSG_TERMINATE);
+
+       term = swap_msg_payload(m);
+       term->pid = task->pid;
+
+       swap_msg_flush(m, sizeof(*term));
+       swap_msg_put(m);
+}
+
+
+
+
+
+/* ============================================================================
+ * =                              MSG_PROCESS_MAP                             =
+ * ============================================================================
+ */
+struct proc_map {
+       u32 pid;
+       u64 low_addr;
+       u64 high_addr;
+       char bin_path[0];
+} __packed;
+
+static int pack_proc_map(void *data, size_t size, struct vm_area_struct *vma)
+{
+       struct proc_map *map = (struct proc_map *)data;
+       int ret;
+
+       map->pid = current->tgid;
+       map->low_addr = vma->vm_start;
+       map->high_addr = vma->vm_end;
+
+       ret = pack_path(map->bin_path, size - sizeof(*map), vma->vm_file);
+       if (ret < 0)
+               return ret;
+
+       return ret + sizeof(*map);
+}
+
+void usm_msg_map(struct vm_area_struct *vma)
+{
+       int ret;
+       struct swap_msg *m;
+       void *p;
+       size_t size;
+
+       m = swap_msg_get(MSG_PROC_MAP);
+       p = swap_msg_payload(m);
+       size = swap_msg_size(m);
+
+       ret = pack_proc_map(p, size, vma);
+       if (ret < 0) {
+               printk(USM_PREFIX "ERROR: message process mapping packing, "
+                      "ret=%d\n", ret);
+               goto put_msg;
+       }
+
+       swap_msg_flush(m, ret);
+
+put_msg:
+       swap_msg_put(m);
+}
+
+
+
+
+
+/* ============================================================================
+ * =                             MSG_PROCESS_UNMAP                            =
+ * ============================================================================
+ */
+struct proc_unmap {
+       u32 pid;
+       u64 low_addr;
+       u64 high_addr;
+} __packed;
+
+void usm_msg_unmap(unsigned long start, unsigned long end)
+{
+       struct swap_msg *m;
+       struct proc_unmap *unmap;
+
+       m = swap_msg_get(MSG_PROC_UNMAP);
+
+       unmap = swap_msg_payload(m);
+       unmap->pid = current->tgid;
+       unmap->low_addr = (u64)start;
+       unmap->high_addr = (u64)end;
+
+       swap_msg_flush(m, sizeof(*unmap));
+       swap_msg_put(m);
+}
+
+
+
+
+
+/* ============================================================================
+ * =                             MSG_PROCESS_COMM                             =
+ * ============================================================================
+ */
+struct proc_comm {
+       u32 pid;
+       char comm[0];
+} __packed;
+
+void usm_msg_comm(struct task_struct *task)
+{
+       struct swap_msg *m;
+       struct proc_comm *c;
+
+       m = swap_msg_get(MSG_PROC_COMM);
+
+       c = swap_msg_payload(m);
+       c->pid = task->tgid;
+       get_task_comm(c->comm, task);
+
+       swap_msg_flush(m, sizeof(*c) + strlen(c->comm) + 1);
+       swap_msg_put(m);
+}
diff --git a/us_manager/usm_msg.h b/us_manager/usm_msg.h
new file mode 100644 (file)
index 0000000..c144817
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2015
+ *
+ * 2015         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ */
+
+
+#ifndef _USM_MSG_H
+#define _USM_MSG_H
+
+
+struct dentry;
+struct task_struct;
+struct vm_area_struct;
+
+
+void usm_msg_info(struct task_struct *task, struct dentry *dentry);
+void usm_msg_term(struct task_struct *task);
+void usm_msg_map(struct vm_area_struct *vma);
+void usm_msg_unmap(unsigned long start, unsigned long end);
+void usm_msg_comm(struct task_struct *task);
+
+
+#endif /* _USM_MSG_H */
index 8c24f5f..b6eef32 100644 (file)
@@ -3,4 +3,5 @@ EXTRA_CFLAGS := $(extra_cflags)
 obj-m := swap_webprobe.o
 swap_webprobe-y := webprobe.o \
                    webprobe_debugfs.o \
-                   webprobe_prof.o
+                   webprobe_prof.o \
+                   web_msg.o
diff --git a/webprobe/web_msg.c b/webprobe/web_msg.c
new file mode 100644 (file)
index 0000000..07b24fb
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2015
+ *
+ * 2015         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ */
+
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/stddef.h>
+#include <linux/uaccess.h>
+#include <writer/swap_msg.h>
+#include <writer/event_filter.h>
+#include <swap-asm/swap_uprobes.h>
+
+
+#define WEB_PREFIX      KERN_INFO "[WEB_PROF] "
+
+/* TODO: develop method for obtaining this data during build... */
+/* location: webkit2-efl-123997_0.11.113/Source/WTF/wtf/text/StringImpl.h:70 */
+struct MStringImpl {
+       unsigned m_refCount;
+       unsigned m_length;
+       union {
+               const unsigned char *m_data8;
+               const unsigned short *m_data16;
+       };
+       union {
+               void *m_buffer;
+               struct MStringImpl *m_substringBuffer;
+               unsigned short *m_copyData16;
+       };
+       unsigned m_hashAndFlags;
+};
+
+/* location: webkit2-efl-123997_0.11.113/Source/JavaScriptCore/profiler/
+ * CallIdentifier.h:36
+ */
+struct MCallIdentifier {
+       struct MStringImpl *m_name;
+       struct MStringImpl *m_url;
+       unsigned m_lineNumber;
+};
+
+enum {
+       OFFSET_NAME = offsetof(struct MCallIdentifier, m_name),
+       OFFSET_URL = offsetof(struct MCallIdentifier, m_url),
+       OFFSET_LNUM = offsetof(struct MCallIdentifier, m_lineNumber)
+};
+
+
+static int pack_web_string(void *data, size_t size,
+                          struct MStringImpl __user *str_imp)
+{
+       int ret;
+       char __user *str;
+       unsigned len;
+       char __user **pstr;
+       unsigned __user *plen;
+
+       pstr = (void __user *)str_imp + offsetof(struct MStringImpl, m_data8);
+       plen = (void __user *)str_imp + offsetof(struct MStringImpl, m_length);
+
+       if (get_user(str, pstr) ||
+           get_user(len, plen)) {
+               printk(WEB_PREFIX "%s: cannot read user memory\n", __func__);
+               return -EPERM;
+       }
+
+       if (size < len + 1) {
+               printk(WEB_PREFIX "function name is very long(len=%u)\n", len);
+               return -ENOMEM;
+       }
+
+       ret = strncpy_from_user(data, str, len);
+       if (ret < 0) {
+               printk(WEB_PREFIX "%s: cannot read user memory\n", __func__);
+               return ret;
+       }
+
+       ((char *)data)[ret] = '\0';
+
+       return ret + 1;
+}
+
+
+void web_msg_entry(struct pt_regs *regs)
+{
+       int ret;
+       struct swap_msg *m;
+       void *p;
+       long t_name, t_url;
+       unsigned lnum;
+       size_t pack_size = 0, size;
+       struct MCallIdentifier *call_id;
+       struct task_struct *task = current;
+
+       if (!check_event(task))
+               return;
+
+       call_id = (void *)swap_get_uarg(regs, 2);
+       if (get_user(t_name, (long *)((long)call_id + OFFSET_NAME)) ||
+           get_user(t_url, (long *)((long)call_id + OFFSET_URL)) ||
+           get_user(lnum, (unsigned *)((long)call_id + OFFSET_LNUM))) {
+               printk(WEB_PREFIX "%s: cannot read user memory\n", __func__);
+               return;
+       }
+
+       m = swap_msg_get(MSG_WEB_FUNCTION_ENTRY);
+       p = swap_msg_payload(m);
+       size = swap_msg_size(m);
+
+       /* Pack message */
+       /* PID */
+       *(u32 *)p = task->tgid;
+       p += sizeof(u32);
+       /* TID */
+       *(u32 *)p = task->pid;
+       p += sizeof(u32);
+       /* Line number (in source file) */
+       *(u32 *)p = lnum;
+       p += sizeof(u32);
+
+       size -= 3 * sizeof(u32);
+       pack_size += 3 * sizeof(u32);
+
+       /* Function name */
+       ret = pack_web_string(p, size, (struct MStringImpl *)t_name);
+       if (ret < 0)
+               goto put_msg;
+
+       size -= ret;
+       pack_size += ret;
+
+       /* URL (source file) */
+       ret = pack_web_string(p, size, (struct MStringImpl *)t_url);
+       if (ret < 0)
+               goto put_msg;
+
+       swap_msg_flush(m, pack_size + ret);
+
+put_msg:
+       swap_msg_put(m);
+}
+
+void web_msg_exit(struct pt_regs *regs)
+{
+       int ret;
+       struct swap_msg *m;
+       void *p;
+       long t_name;
+       size_t pack_size = 0, size;
+       struct MCallIdentifier *call_id;
+       struct task_struct *task = current;
+
+       if (!check_event(task))
+               return;
+
+       call_id = (void *)swap_get_uarg(regs, 2);
+       if (get_user(t_name, (long *)((long)call_id + OFFSET_NAME))) {
+               printk(WEB_PREFIX "%s: cannot read user memory\n", __func__);
+               return;
+       }
+
+       m = swap_msg_get(MSG_WEB_FUNCTION_EXIT);
+       p = swap_msg_payload(m);
+       size = swap_msg_size(m);
+
+       /* PID */
+       *(u32 *)p = task->tgid;
+       p += sizeof(u32);
+
+       /* TID */
+       *(u32 *)p = task->pid;
+       p += sizeof(u32);
+
+       size -= 2 * sizeof(u32);
+       pack_size += 2 * sizeof(u32);
+
+       /* Function name */
+       ret = pack_web_string(p, size, (struct MStringImpl *)t_name);
+       if (ret < 0)
+               goto put_msg;
+
+       swap_msg_flush(m, pack_size + ret);
+
+put_msg:
+       swap_msg_put(m);
+}
diff --git a/webprobe/web_msg.h b/webprobe/web_msg.h
new file mode 100644 (file)
index 0000000..209562b
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2015
+ *
+ * 2015         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ */
+
+
+#ifndef _WEB_MSG_H
+#define _WEB_MSG_H
+
+
+struct pt_regs;
+
+
+void web_msg_entry(struct pt_regs *regs);
+void web_msg_exit(struct pt_regs *regs);
+
+
+#endif /* _WEB_MSG_H */
index 96fa006..5de8fea 100644 (file)
@@ -32,7 +32,6 @@
 #include <us_manager/sspt/ip.h>
 #include <us_manager/probes/register_probes.h>
 #include <us_manager/sspt/sspt.h>
-#include <writer/swap_writer_module.h>
 #include <uprobe/swap_uprobes.h>
 #include <parser/msg_cmd.h>
 #include <linux/module.h>
@@ -41,6 +40,7 @@
 
 #include "webprobe_debugfs.h"
 #include "webprobe_prof.h"
+#include "web_msg.h"
 
 
 static unsigned long inspserver_addr_local;
@@ -104,11 +104,11 @@ static int web_entry_handler(struct uretprobe_instance *ri,
                if (addr == web_prof_addr(WILL_EXECUTE) &&
                    d == web_prof_lib_dentry()) {
                        willexecute_addr_local = ip->orig_addr;
-                       return entry_web_event(addr, regs);
+                       web_msg_entry(regs);
                } else if (addr == web_prof_addr(DID_EXECUTE) &&
                           d == web_prof_lib_dentry()) {
                        didexecute_addr_local = ip->orig_addr;
-                       return exit_web_event(addr, regs);
+                       web_msg_exit(regs);
                }
        }
 
index 1df96c8..1c938cf 100644 (file)
@@ -5,7 +5,6 @@ KBUILD_EXTRA_SYMBOLS = $(src)/../buffer/Module.symvers \
 obj-m := swap_writer.o
 swap_writer-y := swap_writer_module.o \
                  debugfs_writer.o \
-                 event_filter.o
+                 event_filter.o \
+                 swap_msg.o
 
-swap_writer-$(CONFIG_ARM) += kernel_operations_arm.o
-swap_writer-$(CONFIG_X86) += kernel_operations_x86.o
index 1fbb706..b577bf7 100644 (file)
@@ -35,7 +35,7 @@
 #include <asm/uaccess.h>
 #include <master/swap_debugfs.h>
 #include <master/swap_initializer.h>
-#include "swap_writer_module.h"
+#include "swap_msg.h"
 #include "event_filter.h"
 
 
@@ -93,7 +93,7 @@ static ssize_t write_raw(struct file *file, const char __user *user_buf,
                goto put_buf;
        }
 
-       ret = raw_msg(buf, count);
+       ret = swap_msg_raw(buf, count);
 
 put_buf:
        put_current_buf();
index eb51ed7..a5014e7 100644 (file)
@@ -33,6 +33,7 @@
 #define __KERNEL_OPERATIONS_H__
 
 #include <linux/kernel.h>
+#include <linux/uaccess.h>
 #include <asm/ptrace.h>
 
 /* MESSAGES */
@@ -89,10 +90,4 @@ static inline u32 get_regs_ret_func(struct pt_regs *regs)
 
 #endif /* CONFIG_arch */
 
-int get_args(unsigned long args[], int cnt, struct pt_regs *regs);
-
-/* Returns shared kernel memory area name if it is found, otherwise - NULL */
-const char *get_shared_kmem(struct mm_struct *mm, unsigned long *start,
-                           unsigned long *end);
-
 #endif /* __KERNEL_OPERATIONS_H__ */
diff --git a/writer/kernel_operations_arm.c b/writer/kernel_operations_arm.c
deleted file mode 100644 (file)
index db9e434..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * writer/kernel_operations_arm.c
- * @author Alexander Aksenov <a.aksenov@samsung.com>
- *
- * @section LICENSE
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * @section COPYRIGHT
- *
- * Copyright (C) Samsung Electronics, 2013
- *
- * @section DESCRIPTION
- *
- * ARM arch-dependent operations.
- */
-
-#include <asm/ptrace.h>
-#include <asm/uaccess.h>
-#include <asm/page.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <generated/autoconf.h>
-
-#include "kernel_operations.h"
-
-
-/* ======================= ARGS ========================== */
-
-/**
- * @brief Returns arg values.
- *
- * @param[out] args Pointer to array where argument values should be stored/
- * @param cnt Arguments count.
- * @param regs Pointer to register data.
- * @return 0.
- */
-int get_args(unsigned long args[], int cnt, struct pt_regs *regs)
-{
-       /* All args, except first 4, are passed on the stack */
-       enum { stack_args = 4 };
-       int i, args_in_regs;
-
-       args_in_regs = cnt < 3 ? cnt : 3;
-
-       /* Get first 4 args from registers */
-       switch (args_in_regs) {
-       case 3:
-               args[3] = regs->ARM_r3;
-       case 2:
-               args[2] = regs->ARM_r2;
-       case 1:
-               args[1] = regs->ARM_r1;
-       case 0:
-               args[0] = regs->ARM_r0;
-       }
-
-       /* Get other args from stack */
-       for (i = stack_args; i < cnt; ++i) {
-               unsigned long *args_in_sp = (unsigned long *)regs->ARM_sp +
-                                           i - stack_args;
-               if (get_user(args[i], args_in_sp))
-                       printk(KERN_INFO "failed to dereference a pointer, addr=%p\n",
-                              args_in_sp);
-       }
-
-       return 0;
-}
-
-
-/* ================== KERNEL SHARED MEM ===================== */
-
-/* CONFIG_VECTORS_BASE used to handle both MMU and non-MMU cases.
- * According to docs (Documentation/arm/memory.txt) all vector addresses
- * are fixed and vectors are always equal to one page, so,
- * end = start + PAGE_SIZE
- * */
-
-/**
- * @brief Gets shared kernel memory addresses.
- *
- * @param mm Pointer to process mm_struct.
- * @param[out] start Pointer to the variable where the first shared mem
- * address should be put.
- * @param[out] end Pointer to the variable where the last shared mem
- * address should be put.
- * @return Pointer to the string with shared mem area name.
- */
-const char *get_shared_kmem(struct mm_struct *mm,
-                           unsigned long *start,
-                           unsigned long *end)
-{
-       *start = CONFIG_VECTORS_BASE;
-       *end = CONFIG_VECTORS_BASE + PAGE_SIZE;
-
-       return "[vectors]";
-}
diff --git a/writer/kernel_operations_x86.c b/writer/kernel_operations_x86.c
deleted file mode 100644 (file)
index 1335ccd..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * writer/kernel_operations_x86.c
- * @author Alexander Aksenov <a.aksenov@samsung.com>
- *
- * @section LICENSE
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * @section COPYRIGHT
- *
- * Copyright (C) Samsung Electronics, 2013
- *
- * @section DESCRIPTION
- *
- * X86 arch-dependent operations.
- */
-
-#include <asm/ptrace.h>
-#include <asm/uaccess.h>
-#include <asm/elf.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include "kernel_operations.h"
-
-
-/* ======================= ARGS ========================== */
-
-/**
- * @brief Returns arg values.
- *
- * @param[out] args Pointer to array where argument values should be stored/
- * @param cnt Arguments count.
- * @param regs Pointer to register data.
- * @return 0.
- */
-int get_args(unsigned long args[], int cnt, struct pt_regs *regs)
-{
-       int i, stack_args = 0;
-
-       /* If we're in kernel mode on x86, get arguments from bx, cx, dx, si,
-        * di, bp
-        */
-       if (!user_mode(regs)) {
-               int args_in_regs;
-               args_in_regs = cnt < 5 ? cnt : 5;
-               stack_args = 6;
-
-               switch (args_in_regs) {
-               case 5:
-                       args[5] = regs->bp;
-               case 4:
-                       args[4] = regs->di;
-               case 3:
-                       args[3] = regs->si;
-               case 2:
-                       args[2] = regs->dx;
-               case 1:
-                       args[1] = regs->cx;
-               case 0:
-                       args[0] = regs->bx;
-               }
-       }
-
-       /* Get other args from stack */
-       for (i = stack_args; i < cnt; ++i) {
-               unsigned long *args_in_sp = (unsigned long *)regs->sp +
-                                           1 + i - stack_args;
-               if (get_user(args[i], args_in_sp))
-                       printk(KERN_INFO "failed to dereference a pointer, addr=%p\n",
-                              args_in_sp);
-       }
-
-       return 0;
-}
-
-
-/* ================== KERNEL SHARED MEM ===================== */
-
-/**
- * @brief Gets shared kernel memory addresses.
- *
- * @param mm Pointer to process mm_struct.
- * @param[out] start Pointer to the variable where the first shared mem
- * address should be put.
- * @param[out] end Pointer to the variable where the last shared mem
- * address should be put.
- * @return Pointer to the string with shared mem area name.
- */
-const char *get_shared_kmem(struct mm_struct *mm, unsigned long *start,
-                           unsigned long *end)
-{
-       unsigned long vdso;
-       struct vm_area_struct *vma_vdso;
-
-       vdso = (unsigned long)mm->context.vdso;
-       vma_vdso = find_vma_intersection(mm, vdso, vdso + 1);
-
-       if (vma_vdso == NULL) {
-               print_err("Cannot get VDSO mapping\n");
-               return NULL;
-       }
-
-       *start = vma_vdso->vm_start;
-       *end = vma_vdso->vm_end;
-
-       return "[vdso]";
-}
diff --git a/writer/swap_msg.c b/writer/swap_msg.c
new file mode 100644 (file)
index 0000000..90a3d53
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2015
+ *
+ * 2015         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ */
+
+
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/ctype.h>
+#include <linux/errno.h>
+#include <linux/atomic.h>
+#include <buffer/swap_buffer_module.h>
+#include <swap-asm/swap_kprobes.h>
+#include <swap-asm/swap_uprobes.h>
+#include "swap_msg.h"
+
+
+#define MSG_PREFIX      KERN_INFO "[SWAP_MSG] "
+
+
+struct swap_msg {
+       u32 msg_id;
+       u32 seq_num;
+       u64 time;
+       u32 len;
+       char payload[0];
+} __packed;
+
+
+static char *cpu_buf[NR_CPUS];
+static atomic_t seq_num = ATOMIC_INIT(-1);
+static atomic_t discarded = ATOMIC_INIT(0);
+
+
+int swap_msg_init(void)
+{
+       size_t i;
+       const size_t end = ((size_t) 0) - 1;
+
+       for (i = 0; i < NR_CPUS; ++i) {
+               cpu_buf[i] = kmalloc(SWAP_MSG_BUF_SIZE, GFP_KERNEL);
+               if (cpu_buf[i] == NULL)
+                       goto no_mem;
+       }
+
+       return 0;
+
+no_mem:
+       --i;
+       for (; i != end; --i)
+               kfree(cpu_buf[i]);
+
+       return -ENOMEM;
+}
+
+void swap_msg_exit(void)
+{
+       int i;
+
+       for (i = 0; i < NR_CPUS; ++i)
+               kfree(cpu_buf[i]);
+}
+
+void swap_msg_seq_num_reset(void)
+{
+       atomic_set(&seq_num, -1);
+}
+EXPORT_SYMBOL_GPL(swap_msg_seq_num_reset);
+
+void swap_msg_discard_reset(void)
+{
+       atomic_set(&discarded, 0);
+}
+EXPORT_SYMBOL_GPL(swap_msg_discard_reset);
+
+int swap_msg_discard_get(void)
+{
+       return atomic_read(&discarded);
+}
+EXPORT_SYMBOL_GPL(swap_msg_discard_get);
+
+
+u64 swap_msg_timespec2time(struct timespec *ts)
+{
+       return ((u64)ts->tv_nsec) << 32 | ts->tv_sec;
+}
+
+
+
+
+
+struct swap_msg *swap_msg_get(enum swap_msg_id id)
+{
+       struct timespec ts;
+       struct swap_msg *m;
+
+       getnstimeofday(&ts);
+
+       m = (struct swap_msg *)cpu_buf[get_cpu()];
+
+       m->msg_id = (u32)id;
+       m->seq_num = atomic_inc_return(&seq_num);
+       m->time = swap_msg_spec2time(&ts);
+
+       return m;
+}
+EXPORT_SYMBOL_GPL(swap_msg_get);
+
+int swap_msg_flush(struct swap_msg *m, size_t size)
+{
+       if (unlikely(size >= SWAP_MSG_PAYLOAD_SIZE))
+               return -ENOMEM;
+
+       m->len = size;
+
+       if (swap_buffer_write(m, SWAP_MSG_PRIV_DATA + size)) {
+               atomic_inc(&discarded);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(swap_msg_flush);
+
+void swap_msg_put(struct swap_msg *m)
+{
+       put_cpu();
+}
+EXPORT_SYMBOL_GPL(swap_msg_put);
+
+
+
+
+
+
+static unsigned long get_arg(struct pt_regs *regs, unsigned long n)
+{
+       return user_mode(regs) ?
+                       swap_get_uarg(regs, n) :        /* US argument */
+                       swap_get_sarg(regs, n);         /* sys_call argument */
+}
+
+int swap_msg_pack_args(char *buf, int len,
+                      const char *fmt, struct pt_regs *regs)
+{
+       char *buf_old = buf;
+       u32 *tmp_u32;
+       u64 *tmp_u64;
+       int i,          /* the index of the argument */
+           fmt_i,      /* format index */
+           fmt_len;    /* the number of parameters, in format */
+
+       fmt_len = strlen(fmt);
+
+       for (i = 0, fmt_i = 0; fmt_i < fmt_len; ++i, ++fmt_i) {
+               if (len < 2)
+                       return -ENOMEM;
+
+               *buf = fmt[fmt_i];
+               buf += 1;
+               len -= 1;
+
+               switch (fmt[fmt_i]) {
+               case 'b': /* 1 byte(bool) */
+                       if (len < 1)
+                               return -ENOMEM;
+                       *buf = (char)!!get_arg(regs, i);
+                       buf += 1;
+                       len -= 1;
+                       break;
+               case 'c': /* 1 byte(char) */
+                       if (len < 1)
+                               return -ENOMEM;
+                       *buf = (char)get_arg(regs, i);
+                       buf += 1;
+                       len -= 1;
+                       break;
+               case 'f': /* 4 byte(float) */
+               case 'd': /* 4 byte(int) */
+                       if (len < 4)
+                               return -ENOMEM;
+                       tmp_u32 = (u32 *)buf;
+                       *tmp_u32 = (u32)get_arg(regs, i);
+                       buf += 4;
+                       len -= 4;
+                       break;
+               case 'x': /* 8 byte(long) */
+               case 'p': /* 8 byte(pointer) */
+                       if (len < 8)
+                               return -ENOMEM;
+                       tmp_u64 = (u64 *)buf;
+                       *tmp_u64 = (u64)get_arg(regs, i);
+                       buf += 8;
+                       len -= 8;
+                       break;
+               case 'w': /* 8 byte(double) */
+                       if (len < 8)
+                               return -ENOMEM;
+                       tmp_u64 = (u64 *)buf;
+                       *tmp_u64 = get_arg(regs, i);
+                       ++i;
+                       *tmp_u64 |= (u64)get_arg(regs, i) << 32;
+                       buf += 8;
+                       len -= 8;
+                       break;
+               case 's': /* string end with '\0' */
+               {
+                       enum { max_str_len = 512 };
+                       const char __user *user_s;
+                       int len_s, ret;
+
+                       user_s = (const char __user *)get_arg(regs, i);
+                       len_s = strnlen_user(user_s, max_str_len);
+                       if (len < len_s)
+                               return -ENOMEM;
+
+                       ret = strncpy_from_user(buf, user_s, len_s);
+                       if (ret < 0)
+                               return -EFAULT;
+
+                       buf[ret] = '\0';
+
+                       buf += ret + 1;
+                       len -= ret + 1;
+               }
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       return buf - buf_old;
+}
+EXPORT_SYMBOL_GPL(swap_msg_pack_args);
+
+int swap_msg_pack_ret_val(char *buf, int len,
+                         char ret_type, struct pt_regs *regs)
+{
+       const char *buf_old = buf;
+       u32 *tmp_u32;
+       u64 *tmp_u64;
+
+       *buf = ret_type;
+       ++buf;
+
+       switch (ret_type) {
+       case 'b': /* 1 byte(bool) */
+               if (len < 1)
+                       return -ENOMEM;
+               *buf = (char)!!regs_return_value(regs);
+               ++buf;
+               break;
+       case 'c': /* 1 byte(char) */
+               if (len < 1)
+                       return -ENOMEM;
+               *buf = (char)regs_return_value(regs);
+               ++buf;
+               break;
+       case 'd': /* 4 byte(int) */
+               if (len < 4)
+                       return -ENOMEM;
+               tmp_u32 = (u32 *)buf;
+               *tmp_u32 = regs_return_value(regs);
+               buf += 4;
+               break;
+       case 'x': /* 8 byte(long) */
+       case 'p': /* 8 byte(pointer) */
+               if (len < 8)
+                       return -ENOMEM;
+               tmp_u64 = (u64 *)buf;
+               *tmp_u64 = (u64)regs_return_value(regs);
+               buf += 8;
+               break;
+       case 's': /* string end with '\0' */
+       {
+               enum { max_str_len = 512 };
+               const char __user *user_s;
+               int len_s, ret;
+
+               user_s = (const char __user *)regs_return_value(regs);
+               len_s = strnlen_user(user_s, max_str_len);
+               if (len < len_s)
+                       return -ENOMEM;
+
+               ret = strncpy_from_user(buf, user_s, len_s);
+               if (ret < 0)
+                       return -EFAULT;
+
+               buf[ret] = '\0';
+               buf += ret + 1;
+       }
+               break;
+       case 'n':
+       case 'v':
+               break;
+       case 'f': /* 4 byte(float) */
+               if (len < 4)
+                       return -ENOMEM;
+               tmp_u32 = (u32 *)buf;
+               *tmp_u32 = swap_get_urp_float(regs);
+               buf += 4;
+               break;
+       case 'w': /* 8 byte(double) */
+               if (len < 8)
+                       return -ENOMEM;
+               tmp_u64 = (u64 *)buf;
+               *tmp_u64 = swap_get_urp_double(regs);
+               buf += 8;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return buf - buf_old;
+}
+EXPORT_SYMBOL_GPL(swap_msg_pack_ret_val);
+
+
+
+
+
+int swap_msg_raw(void *data, size_t size)
+{
+       struct swap_msg *m = (struct swap_msg *)data;
+
+       if (sizeof(*m) > size) {
+               printk(MSG_PREFIX "ERROR: message RAW small size=%u\n", size);
+               return -EINVAL;
+       }
+
+       if (m->len + sizeof(*m) != size) {
+               printk(MSG_PREFIX "ERROR: message RAW wrong format\n");
+               return -EINVAL;
+       }
+
+       m->seq_num = atomic_inc_return(&seq_num);
+
+       /* TODO: What should be returned?! When message was discarded. */
+       if (swap_buffer_write(m, size))
+               atomic_inc(&discarded);
+
+       return size;
+}
+EXPORT_SYMBOL_GPL(swap_msg_raw);
+
+void swap_msg_error(const char *fmt, ...)
+{
+       int ret;
+       struct swap_msg *m;
+       void *p;
+       size_t size;
+       va_list args;
+
+       m = swap_msg_get(MSG_ERROR);
+       p = swap_msg_payload(m);
+       size = swap_msg_size(m);
+
+       va_start(args, fmt);
+       ret = vsnprintf(p, size, fmt, args);
+       va_end(args);
+
+       if (ret <= 0) {
+               printk(MSG_PREFIX "ERROR: msg error packing, ret=%d\n", ret);
+               goto put_msg;
+       }
+
+       swap_msg_flush(m, ret + 1);
+
+put_msg:
+       swap_msg_put(m);
+}
+EXPORT_SYMBOL_GPL(swap_msg_error);
diff --git a/writer/swap_msg.h b/writer/swap_msg.h
new file mode 100644 (file)
index 0000000..c3c3488
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2015
+ *
+ * 2015         Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ */
+
+
+#ifndef _SWAP_MSG_H
+#define _SWAP_MSG_H
+
+
+#include <linux/time.h>
+#include <linux/types.h>
+
+
+enum swap_msg_id {
+       MSG_PROC_INFO                   = 0x0001,
+       MSG_TERMINATE                   = 0x0002,
+       MSG_ERROR                       = 0x0003,
+       MSG_SAMPLE                      = 0x0004,
+       MSG_FUNCTION_ENTRY              = 0x0008,
+       MSG_FUNCTION_EXIT               = 0x0009,
+       MSG_SYSCALL_ENTRY               = 0x000a,
+       MSG_SYSCALL_EXIT                = 0x000b,
+       MSG_FILE_FUNCTION_ENTRY         = 0x000c,
+       MSG_FILE_FUNCTION_EXIT          = 0x000d,
+       MSG_CONTEXT_SWITCH_ENTRY        = 0x0010,
+       MSG_CONTEXT_SWITCH_EXIT         = 0x0011,
+       MSG_PROC_MAP                    = 0x0012,
+       MSG_PROC_UNMAP                  = 0x0013,
+       MSG_PROC_COMM                   = 0x0014,
+       MSG_WEB_FUNCTION_ENTRY          = 0x0015,
+       MSG_WEB_FUNCTION_EXIT           = 0x0016
+};
+
+enum {
+       SWAP_MSG_PRIV_DATA = 20,
+       SWAP_MSG_BUF_SIZE = 32 * 1024,
+       SWAP_MSG_PAYLOAD_SIZE = SWAP_MSG_BUF_SIZE - SWAP_MSG_PRIV_DATA
+};
+
+
+struct swap_msg;
+
+
+static inline u64 swap_msg_spec2time(struct timespec *ts)
+{
+       return ((u64)ts->tv_nsec) << 32 | ts->tv_sec;
+}
+
+struct swap_msg *swap_msg_get(enum swap_msg_id id);
+int swap_msg_flush(struct swap_msg *m, size_t size);
+void swap_msg_put(struct swap_msg *m);
+
+static inline void *swap_msg_payload(struct swap_msg *m)
+{
+       return (void *)m + SWAP_MSG_PRIV_DATA;
+}
+
+static inline size_t swap_msg_size(struct swap_msg *m)
+{
+       return (size_t)SWAP_MSG_PAYLOAD_SIZE;
+}
+
+
+int swap_msg_pack_args(char *buf, int len,
+                      const char *fmt, struct pt_regs *regs);
+int swap_msg_pack_ret_val(char *buf, int len,
+                         char ret_type, struct pt_regs *regs);
+
+
+int swap_msg_raw(void *buf, size_t size);
+void swap_msg_error(const char *fmt, ...);
+
+void swap_msg_seq_num_reset(void);
+void swap_msg_discard_reset(void);
+int swap_msg_discard_get(void);
+
+int swap_msg_init(void);
+void swap_msg_exit(void);
+
+
+#endif /* _SWAP_MSG_H */
index a9d219a..e120b3a 100644 (file)
  * Packing and writing data.
  */
 
-#include <linux/types.h>
-#include <linux/ctype.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/dcache.h>
-#include <linux/mm.h>
-#include <linux/mm_types.h>
-#include <linux/fs.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include <asm/uaccess.h>
 
+#include <linux/module.h>
 #include <master/swap_initializer.h>
-#include <buffer/swap_buffer_module.h>
-#include <buffer/swap_buffer_errors.h>
-
-#include <swap-asm/swap_kprobes.h>
-#include <swap-asm/swap_uprobes.h>
-
-#include "swap_writer_module.h"
-#include "swap_writer_errors.h"
-#include "kernel_operations.h"
-#include "debugfs_writer.h"
+#include "swap_msg.h"
 #include "event_filter.h"
+#include "debugfs_writer.h"
 
 
-/**
- * @enum MSG_ID
- * @brief Supported message IDs.
- */
-enum MSG_ID {
-       MSG_PROC_INFO                   = 0x0001,       /**< Process info */
-       MSG_TERMINATE                   = 0x0002,       /**< Terminate */
-       MSG_ERROR                       = 0x0003,           /**< Error */
-       MSG_SAMPLE                      = 0x0004,           /**< Sampler event */
-       MSG_FUNCTION_ENTRY              = 0x0008,       /**< Function entry */
-       MSG_FUNCTION_EXIT               = 0x0009,       /**< Function return */
-       MSG_CONTEXT_SWITCH_ENTRY        = 0x0010,   /**< Context switch entry */
-       MSG_CONTEXT_SWITCH_EXIT         = 0x0011,   /**< Context switch exit */
-       MSG_PROC_MAP                    = 0x0012,       /**< Process map */
-       MSG_PROC_UNMAP                  = 0x0013,       /**< Process unmap */
-       MSG_PROC_COMM                   = 0x0014,       /**< Process comm */
-       MSG_WEB_FUNCTION_ENTRY          = 0x0015,   /**< Web function entry */
-       MSG_WEB_FUNCTION_EXIT           = 0x0016    /**< Web function exit */
-};
-
-static char *cpu_buf[NR_CPUS];
-static u32 seq_num;
-static unsigned int discarded;
-
-/**
- * @brief Initializes new message.
- *
- * @param buf_size Message buffer size.
- * @return Success.
- */
-int init_msg(size_t buf_size)
-{
-       int i;
-
-       for (i = 0; i < NR_CPUS; ++i)
-               cpu_buf[i] = kmalloc(buf_size, GFP_KERNEL);
-
-       return E_SW_SUCCESS;
-}
-EXPORT_SYMBOL_GPL(init_msg);
-
-/**
- * @brief Uninitializes message.
- *
- * @return Void.
- */
-void uninit_msg(void)
-{
-       int i;
-
-       for (i = 0; i < NR_CPUS; ++i)
-               kfree(cpu_buf[i]);
-}
-EXPORT_SYMBOL_GPL(uninit_msg);
-
-/**
- * @brief Sets discarded events count to 0.
- *
- * @return Void.
- */
-void reset_discarded(void)
-{
-       discarded = 0;
-}
-EXPORT_SYMBOL_GPL(reset_discarded);
-
-/**
- * @brief Sets events sequence number to 0.
- *
- * @return Void.
- */
-void reset_seq_num(void)
-{
-       seq_num = 0;
-}
-EXPORT_SYMBOL_GPL(reset_seq_num);
-
-/**
- * @brief Gets discarded events count.
- *
- * @return Discarded events count.
- */
-unsigned int get_discarded_count(void)
-{
-       return discarded;
-}
-EXPORT_SYMBOL_GPL(get_discarded_count);
-
-static inline char *get_current_buf(void)
-{
-       return cpu_buf[get_cpu()];
-}
-
-static inline void put_current_buf(void)
-{
-       put_cpu();
-}
-
-static inline u64 timespec2time(struct timespec *ts)
-{
-       return ((u64)ts->tv_nsec) << 32 | ts->tv_sec;
-}
-
-/* ============================================================================
- * =                         BASIC MESSAGE FORMAT                             =
- * ============================================================================
- */
-
-/**
- * @struct basic_msg_fmt
- * @brief Basic message.
- */
-struct basic_msg_fmt {
-       u32 msg_id;             /**< Message ID */
-       u32 seq_number;         /**< Sequence number */
-       u64 time;               /**< Message time */
-       u32 len;                /**< Message length */
-       char payload[0];        /**< Message itself */
-} __packed;
-
-#if 0 /* debug */
-static void print_hex(char *ptr, int len)
-{
-       int i;
-
-       printk(KERN_INFO "print_hex:\n");
-       for (i = 0; i < len; ++i)
-               printk(KERN_INFO "[%x]  [%3d]=%2x\n", &ptr[i], i, ptr[i]);
-}
-#endif
-
-static int write_to_buffer(void *data)
-{
-       int result;
-       struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)data;
-
-       result = swap_buffer_write(bmf, bmf->len + sizeof(*bmf));
-       if (result < 0)
-               discarded++;
-
-       return result;
-}
-
-static void set_len_msg(char *buf, char *end)
-{
-       struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
-       bmf->len = end - buf - sizeof(*bmf);
-}
-
-static inline void set_seq_num(struct basic_msg_fmt *bmf)
-{
-       bmf->seq_number = seq_num;
-       seq_num++;
-}
-
-static inline void set_time(struct basic_msg_fmt *bmf)
-{
-       struct timespec ts;
-
-       getnstimeofday(&ts);
-       bmf->time = timespec2time(&ts);
-}
-
-static char *pack_basic_msg_fmt(char *buf, enum MSG_ID id)
-{
-       struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
-
-       set_time(bmf);
-       set_seq_num(bmf);
-       bmf->msg_id = id;
-
-       return bmf->payload;
-}
-
-
-
-
-
-/* ============================================================================
- * =                             PROCESS INFO                                 =
- * ============================================================================
- */
-
-/**
- * @struct proc_info_top
- * @brief Top proc info part.
- */
-struct proc_info_top {
-       u32 pid;                    /**< Process PID */
-       char comm[0];               /**< Message */
-} __packed;
-
-/**
- * @struct proc_info_bottom
- * @brief Bottom proc info part.
- */
-struct proc_info_bottom {
-       u32 ppid;                   /**< Parent PID */
-       u32 start_sec;              /**< Start time sec */
-       u32 start_nsec;             /**< Start time nsec */
-       u64 low_addr;               /**< Low address */
-       u64 high_addr;              /**< High address */
-       char bin_path[0];           /**< Binary path */
-} __packed;
-
-/**
- * @struct proc_info_part
- * @brief Process info part.
- */
-struct proc_info_part {
-       u32 lib_cnt;                /**< Library count */
-       char libs[0];               /**< Libraries */
-} __packed;
-
-/**
- * @struct lib_obj
- * @brief Library object.
- */
-struct lib_obj {
-       u64 low_addr;               /**< Low library address */
-       u64 high_addr;              /**< High library address */
-       char lib_path[0];           /**< Library path */
-} __packed;
-
-static char *pack_path(char *buf, struct file *file)
-{
-       enum { TMP_BUF_LEN = 512 };
-       char tmp_buf[TMP_BUF_LEN];
-       char NA[] = "N/A";
-       char *filename;
-       size_t len;
-
-       if (file == NULL)
-               return strcpy(buf, NA) + sizeof(NA);
-
-       filename = d_path(&file->f_path, tmp_buf, TMP_BUF_LEN);
-       if (IS_ERR_OR_NULL(filename))
-               return strcpy(buf, NA) + sizeof(NA);
-
-       len = strlen(filename) + 1;
-       memcpy(buf, filename, len);
-
-       return buf + len;
-}
-
-static char *pack_lib_obj(char *lib_obj, struct vm_area_struct *vma)
-{
-       struct lib_obj *lo = (struct lib_obj *)lib_obj;
-
-       lo->low_addr = vma->vm_start;
-       lo->high_addr = vma->vm_end;
-
-       return pack_path(lo->lib_path, vma->vm_file);
-}
-
-/* FIXME: check_vma()*/
-static int check_vma(struct vm_area_struct *vma)
-{
-       return vma->vm_file &&
-              !(vma->vm_pgoff != 0 ||
-                !(vma->vm_flags & VM_EXEC) ||
-                !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
-}
-
-static struct vm_area_struct *find_vma_exe_by_dentry(struct mm_struct *mm,
-                                                    struct dentry *dentry)
-{
-       struct vm_area_struct *vma;
-
-       for (vma = mm->mmap; vma; vma = vma->vm_next) {
-               if (vma->vm_file && (vma->vm_flags & VM_EXEC) &&
-                  (vma->vm_file->f_dentry == dentry))
-                       goto out;
-       }
-
-       vma = NULL;
-out:
-
-       return vma;
-}
-
-static char *pack_shared_kmem(char *lib_obj,
-                             struct mm_struct *mm,
-                             u32 *lib_cnt_p)
-{
-       struct lib_obj *so = (struct lib_obj *)lib_obj;
-       char *so_obj;
-       unsigned long start = 0, end = 0;
-
-       const char *kmem_name = get_shared_kmem(mm, &start, &end);
-       size_t name_len;
-
-       if (kmem_name == NULL)
-               return lib_obj;
-
-       name_len = strlen(kmem_name) + 1;
-       so->low_addr = (u64)start;
-       so->high_addr = (u64)end;
-       memcpy(so->lib_path, kmem_name, name_len);
-       (*lib_cnt_p)++;
-       so_obj = so->lib_path + name_len;
-
-       return so_obj;
-}
-
-static char *pack_libs(char *lib_obj, struct mm_struct *mm, u32 *lib_cnt_p)
-{
-       struct vm_area_struct *vma;
-
-       for (vma = mm->mmap; vma; vma = vma->vm_next) {
-               if (check_vma(vma)) {
-                       lib_obj = pack_lib_obj(lib_obj, vma);
-                       ++(*lib_cnt_p);
-               }
-       }
-
-       return lib_obj;
-}
-
-static char *pack_proc_info_part(char *end_path, struct mm_struct *mm)
-{
-       struct proc_info_part *pip;
-       char *lib_obj;
-       u32 *lib_cnt_p;
-
-       pip = (struct proc_info_part *)end_path;
-       pip->lib_cnt = 0;
-       lib_obj = pip->libs;
-       lib_cnt_p = &pip->lib_cnt;
-
-       lib_obj = pack_libs(lib_obj, mm, lib_cnt_p);
-       lib_obj = pack_shared_kmem(lib_obj, mm, lib_cnt_p);
-
-       return lib_obj;
-}
-
-static char *pack_comm(char *buf, struct task_struct *task)
-{
-       get_task_comm(buf, task);
-
-       return buf + strlen(buf) + 1;
-}
-
-static char *pack_proc_info_top(char *data, struct task_struct *task)
-{
-       struct proc_info_top *pit = (struct proc_info_top *)data;
-
-       pit->pid = task->tgid;
-
-       return pack_comm(pit->comm, task);
-}
-
-static char *pack_proc_info_bottom(char *data, struct task_struct *task,
-                                  struct dentry *dentry)
-{
-       struct proc_info_bottom *pib = (struct proc_info_bottom *)data;
-       struct vm_area_struct *vma = find_vma_exe_by_dentry(task->mm, dentry);
-       struct timespec boot_time;
-       struct timespec start_time;
-       char *end_path = NULL;
-
-       getboottime(&boot_time);
-       start_time = timespec_add(boot_time, task->real_start_time);
-
-       pib->ppid = task->real_parent->tgid;
-       pib->start_sec = (u32)start_time.tv_sec;
-       pib->start_nsec = (u32)start_time.tv_nsec;
-
-       if (vma) {
-               pib->low_addr = vma->vm_start;
-               pib->high_addr = vma->vm_end;
-               end_path = pack_path(pib->bin_path, vma->vm_file);
-       } else {
-               pib->low_addr = 0;
-               pib->high_addr = 0;
-               end_path = pack_path(pib->bin_path, NULL);
-       }
-       return pack_proc_info_part(end_path, task->mm);
-}
-
-static char *pack_proc_info(char *payload, struct task_struct *task,
-                           struct dentry *dentry)
-{
-       payload = pack_proc_info_top(payload, task);
-       return pack_proc_info_bottom(payload, task, dentry);
-}
-
-/**
- * @brief Packs and writes process info message. Called with
- * down\up\_read(&task->mm->mmap_sem).
- *
- * @param task Pointer to the target task_struct.
- * @param dentry Pointer to the task dentry.
- * @return Written data size on success, negative error code on error.
- */
-int proc_info_msg(struct task_struct *task, struct dentry *dentry)
+static int core_init(void)
 {
-       char *buf, *payload, *buf_end;
        int ret;
 
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, MSG_PROC_INFO);
-       buf_end = pack_proc_info(payload, task, dentry);
-
-       set_len_msg(buf, buf_end);
+       ret = swap_msg_init();
+       if (ret)
+               return ret;
 
-       ret = write_to_buffer(buf);
-       put_current_buf();
+       ret = event_filter_init();
+       if (ret)
+               swap_msg_exit();
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(proc_info_msg);
-
-
-
-
-
-/* ============================================================================
- * =                           PROCESS TERMINATE                              =
- * ============================================================================
- */
-
-/**
- * @struct proc_terminate
- * @brief Terminate message struct.
- */
-struct proc_terminate {
-       u32 pid;                /**< Process ID */
-} __packed;
-
-static char *pack_proc_terminate(char *payload, struct task_struct *task)
-{
-       struct proc_terminate *pt = (struct proc_terminate *)payload;
-
-       pt->pid = task->pid;
-       return payload + sizeof(*pt);
-}
-
-/**
- * @brief Packs and writes terminate message.
- *
- * @param task Target task_struct.
- * @return Void.
- */
-void terminate_msg(struct task_struct *task)
-{
-       char *buf, *payload, *buf_end;
-
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, MSG_TERMINATE);
-       buf_end = pack_proc_terminate(payload, task);
-
-       set_len_msg(buf, buf_end);
-
-       write_to_buffer(buf);
-       put_current_buf();
-}
-EXPORT_SYMBOL_GPL(terminate_msg);
-
-
-
-
-
-/* ============================================================================
- * =                             PROCESS MAP                                  =
- * ============================================================================
- */
-
-/**
- * @struct proc_map
- * @brief Process mapping info.
- */
-struct proc_map {
-       u32 pid;                    /**< Process ID */
-       u64 low_addr;               /**< Low address */
-       u64 high_addr;              /**< High address */
-       char bin_path[0];           /**< Binary path */
-} __packed;
-
-static char *pack_proc_map(char *payload, struct vm_area_struct *vma)
-{
-       struct proc_map *pm = (struct proc_map *)payload;
-
-       pm->pid = current->tgid;
-       pm->low_addr = vma->vm_start;
-       pm->high_addr = vma->vm_end;
-
-       return pack_path(pm->bin_path, vma->vm_file);
-}
-
-/**
- * @brief Packs and writes process map message.
- *
- * @param vma Target memory area.
- * @return Void.
- */
-void pcoc_map_msg(struct vm_area_struct *vma)
-{
-       char *buf, *payload, *buf_end;
-
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, MSG_PROC_MAP);
-       buf_end = pack_proc_map(payload, vma);
-
-       set_len_msg(buf, buf_end);
-
-       write_to_buffer(buf);
-       put_current_buf();
-}
-EXPORT_SYMBOL_GPL(pcoc_map_msg);
-
-
-
-
-
-/* ============================================================================
- * =                            PROCESS UNMAP                                 =
- * ============================================================================
- */
-
-/**
- * @struct proc_unmap
- * @brief Process mapping info.
- */
-struct proc_unmap {
-       u32 pid;                /**< Process ID */
-       u64 low_addr;           /**< Low address */
-       u64 high_addr;          /**< High address */
-} __packed;
-
-static char *pack_proc_unmap(char *payload, unsigned long start,
-                            unsigned long end)
-{
-       struct proc_unmap *pum = (struct proc_unmap *)payload;
-
-       pum->pid = current->tgid;
-       pum->low_addr = start;
-       pum->high_addr = end;
-
-       return payload + sizeof(*pum);
-}
-
-/**
- * @brief Packs and writes process unmap message.
- *
- * @param start Unmapping area low address.
- * @param end Unmapping area high address.
- * @return Void.
- */
-void proc_unmap_msg(unsigned long start, unsigned long end)
-{
-       char *buf, *payload, *buf_end;
-
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, MSG_PROC_UNMAP);
-       buf_end = pack_proc_unmap(payload, start, end);
-
-       set_len_msg(buf, buf_end);
-
-       write_to_buffer(buf);
-       put_current_buf();
-}
-EXPORT_SYMBOL_GPL(proc_unmap_msg);
-
-
-
-
-
-/* ============================================================================
- * =                              PROCESS COMM                                =
- * ============================================================================
- */
-
-/**
- * @struct proc_comm
- * @brief Comm message info.
- */
-struct proc_comm {
-       u32 pid;                /**< Process ID */
-       char comm[0];           /**< Comm */
-} __packed;
-
-static char *pack_proc_comm(char *data, struct task_struct *task)
-{
-       struct proc_comm *pcomm = (struct proc_comm *)data;
-
-       pcomm->pid = task->tgid;
-
-       return pack_comm(pcomm->comm, task);
-}
 
-/**
- * @brief Packs and writes process comm message.
- *
- * @param task Target task_struct.
- * @return Void.
- */
-void proc_comm_msg(struct task_struct *task)
+static void core_exit(void)
 {
-       char *buf, *payload, *buf_end;
-
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, MSG_PROC_COMM);
-       buf_end = pack_proc_comm(payload, task);
-
-       set_len_msg(buf, buf_end);
-
-       write_to_buffer(buf);
-       put_current_buf();
+       event_filter_exit();
+       swap_msg_exit();
 }
-EXPORT_SYMBOL_GPL(proc_comm_msg);
-
-
-
-
-
-/* ============================================================================
- * =                                 SAMPLE                                   =
- * ============================================================================
- */
-
-/**
- * @struct sample
- * @brief Sampler event info.
- */
-struct sample {
-       u32 pid;                /**< Process ID */
-       u64 pc_addr;            /**< Instruction pointer address */
-       u32 tid;                /**< Thread ID */
-       u32 cpu_num;            /**< CPU number */
-} __packed;
-
-static char *pack_sample(char *payload, struct pt_regs *regs)
-{
-       struct sample *s = (struct sample *)payload;
-       struct task_struct *task = current;
-
-       s->pid = task->tgid;
-       s->pc_addr = get_regs_ip(regs);
-       s->tid = task->pid;
-       s->cpu_num = smp_processor_id();
-
-       return payload + sizeof(*s);
-}
-
-/**
- * @brief Packs and writes sample message.
- *
- * @param regs Pointer to CPU register data.
- * @return Written data size on success, negative error code on error.
- */
-int sample_msg(struct pt_regs *regs)
-{
-       char *buf, *payload, *buf_end;
-       int ret;
-
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, MSG_SAMPLE);
-       buf_end = pack_sample(payload, regs);
-
-       set_len_msg(buf, buf_end);
-
-       ret = write_to_buffer(buf);
-       put_current_buf();
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(sample_msg);
-
-
-
-
-/* ============================================================================
- * =                                 ENTRY                                    =
- * ============================================================================
- */
-
-/**
- * @struct msg_func_entry
- * @brief Entry event info.
- */
-struct msg_func_entry {
-       u32 pid;                /**< Process ID */
-       u32 tid;                /**< Thread ID */
-       u16 probe_type;         /**< Probe type */
-       u16 probe_sub_type;     /**< Probe subtype */
-       u64 pc_addr;            /**< Instruction pointer address. */
-       u64 caller_pc_addr;     /**< Return address */
-       u32 cpu_num;            /**< CPU number */
-       u32 cnt_args;           /**< Count of args */
-       char args[0];           /**< Args format string */
-} __packed;
-
-static char *pack_msg_func_entry(char *payload, const char *fmt,
-                                unsigned long func_addr, struct pt_regs *regs,
-                                enum PROBE_TYPE pt, int sub_type)
-{
-       struct msg_func_entry *mfe = (struct msg_func_entry *)payload;
-       struct task_struct *task = current;
-
-       mfe->pid = task->tgid;
-       mfe->tid = task->pid;
-       mfe->cpu_num = smp_processor_id();
-       mfe->pc_addr = func_addr;
-       mfe->caller_pc_addr = get_regs_ret_func(regs);
-       mfe->probe_type = pt;
-       mfe->probe_sub_type = sub_type;
-       mfe->cnt_args = strlen(fmt);
-
-       return payload + sizeof(*mfe);
-}
-
-static unsigned long get_arg(struct pt_regs *regs, unsigned long n)
-{
-       return user_mode(regs) ?
-                       swap_get_uarg(regs, n) :        /* US argument */
-                       swap_get_sarg(regs, n);         /* sys_call argument */
-}
-
-static int pack_args(char *buf, int len, const char *fmt, struct pt_regs *regs)
-{
-       char *buf_old = buf;
-       u32 *tmp_u32;
-       u64 *tmp_u64;
-       int i,          /* the index of the argument */
-           fmt_i,      /* format index */
-           fmt_len;    /* the number of parameters, in format */
-
-       fmt_len = strlen(fmt);
-
-       for (i = 0, fmt_i = 0; fmt_i < fmt_len; ++i, ++fmt_i) {
-               if (len < 2)
-                       return -ENOMEM;
-
-               *buf = fmt[fmt_i];
-               buf += 1;
-               len -= 1;
-
-               switch (fmt[fmt_i]) {
-               case 'b': /* 1 byte(bool) */
-                       *buf = (char)!!get_arg(regs, i);
-                       buf += 1;
-                       len -= 1;
-                       break;
-               case 'c': /* 1 byte(char) */
-                       *buf = (char)get_arg(regs, i);
-                       buf += 1;
-                       len -= 1;
-                       break;
-               case 'f': /* 4 byte(float) */
-               case 'd': /* 4 byte(int) */
-                       if (len < 4)
-                               return -ENOMEM;
-                       tmp_u32 = (u32 *)buf;
-                       *tmp_u32 = (u32)get_arg(regs, i);
-                       buf += 4;
-                       len -= 4;
-                       break;
-               case 'x': /* 8 byte(long) */
-               case 'p': /* 8 byte(pointer) */
-                       if (len < 8)
-                               return -ENOMEM;
-                       tmp_u64 = (u64 *)buf;
-                       *tmp_u64 = (u64)get_arg(regs, i);
-                       buf += 8;
-                       len -= 8;
-                       break;
-               case 'w': /* 8 byte(double) */
-                       if (len < 8)
-                               return -ENOMEM;
-                       tmp_u64 = (u64 *)buf;
-                       *tmp_u64 = get_arg(regs, i);
-                       ++i;
-                       *tmp_u64 |= (u64)get_arg(regs, i) << 32;
-                       buf += 8;
-                       len -= 8;
-                       break;
-               case 's': /* string end with '\0' */
-               {
-                       enum { max_str_len = 512 };
-                       const char __user *user_s;
-                       int len_s, ret;
-
-                       user_s = (const char __user *)get_arg(regs, i);
-                       len_s = strnlen_user(user_s, max_str_len);
-                       if (len < len_s)
-                               return -ENOMEM;
-
-                       ret = strncpy_from_user(buf, user_s, len_s);
-                       if (ret < 0)
-                               return -EFAULT;
-
-                       buf[ret] = '\0';
-
-                       buf += ret + 1;
-                       len -= ret + 1;
-               }
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       }
-
-       return buf - buf_old;
-}
-
-/**
- * @brief Packs and writes entry event message.
- *
- * @param fmt Arguments format string.
- * @param func_addr Function address.
- * @param regs CPU register data.
- * @param pt Probe type.
- * @param sub_type Probe sub type.
- * @return Written data size on success, negative error code on error.
- */
-int entry_event(const char *fmt, unsigned long func_addr, struct pt_regs *regs,
-               enum PROBE_TYPE pt, int sub_type)
-{
-       char *buf, *payload, *args, *buf_end;
-       int ret;
-
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_ENTRY);
-       args = pack_msg_func_entry(payload, fmt, func_addr,
-                                  regs, pt, sub_type);
-
-       /* FIXME: len = 1024 */
-       ret = pack_args(args, 1024, fmt, regs);
-       if (ret < 0) {
-               printk(KERN_INFO "ERROR: !!!!!\n");
-               goto put_buf;
-       }
-
-       buf_end = args + ret;
-
-       set_len_msg(buf, buf_end);
-
-       ret = write_to_buffer(buf);
-
-put_buf:
-       put_current_buf();
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(entry_event);
-
-
-
-
-
-/* ============================================================================
- * =                                 EXIT                                     =
- * ============================================================================
- */
-
-/**
- * @struct msg_func_exit
- * @brief Exit event message info.
- */
-struct msg_func_exit {
-       u32 pid;                /**< PID */
-       u32 tid;                /**< TID */
-       u16 probe_type;         /**< Probe type */
-       u16 probe_sub_type;     /**< Probe subtype */
-       u64 pc_addr;            /**< Instruction pointer */
-       u64 caller_pc_addr;     /**< Return address */
-       u32 cpu_num;            /**< CPU number */
-       char ret_val[0];        /**< Return value */
-} __packed;
-
-static int pack_msg_ret_val(char *buf, int len, char ret_type,
-                             struct pt_regs *regs)
-{
-       const char *buf_old = buf;
-       u32 *tmp_u32;
-       u64 *tmp_u64;
-
-       *buf = ret_type;
-       ++buf;
-
-       switch (ret_type) {
-       case 'b': /* 1 byte(bool) */
-               if (len < 1)
-                       return -ENOMEM;
-               *buf = (char)!!get_regs_ret_val(regs);
-               ++buf;
-               break;
-       case 'c': /* 1 byte(char) */
-               if (len < 1)
-                       return -ENOMEM;
-               *buf = (char)get_regs_ret_val(regs);
-               ++buf;
-               break;
-       case 'd': /* 4 byte(int) */
-               if (len < 4)
-                       return -ENOMEM;
-               tmp_u32 = (u32 *)buf;
-               *tmp_u32 = get_regs_ret_val(regs);
-               buf += 4;
-               break;
-       case 'x': /* 8 byte(long) */
-       case 'p': /* 8 byte(pointer) */
-               if (len < 8)
-                       return -ENOMEM;
-               tmp_u64 = (u64 *)buf;
-               *tmp_u64 = (u64)get_regs_ret_val(regs);
-               buf += 8;
-               break;
-       case 's': /* string end with '\0' */
-       {
-               enum { max_str_len = 512 };
-               const char __user *user_s;
-               int len_s, ret;
-
-               user_s = (const char __user *)get_regs_ret_val(regs);
-               len_s = strnlen_user(user_s, max_str_len);
-               if (len < len_s)
-                       return -ENOMEM;
-
-               ret = strncpy_from_user(buf, user_s, len_s);
-               if (ret < 0)
-                       return -EFAULT;
-
-               buf[ret] = '\0';
-               buf += ret + 1;
-       }
-               break;
-       case 'n':
-       case 'v':
-               break;
-       case 'f': /* 4 byte(float) */
-               if (len < 4)
-                       return -ENOMEM;
-               tmp_u32 = (u32 *)buf;
-               *tmp_u32 = swap_get_urp_float(regs);
-               buf += 4;
-               break;
-       case 'w': /* 8 byte(double) */
-               if (len < 8)
-                       return -ENOMEM;
-               tmp_u64 = (u64 *)buf;
-               *tmp_u64 = swap_get_urp_double(regs);
-               buf += 8;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return buf - buf_old;
-}
-
-
-static int pack_msg_func_exit(char *buf, int len, char ret_type,
-                             struct pt_regs *regs, int pt, int sub_type,
-                             unsigned long func_addr, unsigned long ret_addr)
-{
-       struct msg_func_exit *mfe = (struct msg_func_exit *)buf;
-       struct task_struct *task = current;
-       int ret;
-
-       mfe->pid = task->tgid;
-       mfe->tid = task->pid;
-       mfe->probe_type = pt;
-       mfe->probe_sub_type = sub_type;
-       mfe->cpu_num = smp_processor_id();
-       mfe->pc_addr = func_addr;
-       mfe->caller_pc_addr = ret_addr;
-
-       ret = pack_msg_ret_val(mfe->ret_val, len, ret_type, regs);
-       if (ret < 0) {
-               printk(KERN_INFO "ERROR: packing MSG_FUNCTION_EXIT (ret=%d)\n",
-                      ret);
-               return ret;
-       }
-
-       return sizeof(*mfe) + ret;
-}
-
-/**
- * @brief Packs and writes exit event.
- *
- * @param ret_type Return value type.
- * @param regs CPU register data.
- * @param sub_type Event subtype.
- * @param func_addr Function address.
- * @param ret_addr Return address.
- * @return Written data size on success, negative error code on error.
- */
-int exit_event(char ret_type, struct pt_regs *regs, int pt, int sub_type,
-              unsigned long func_addr, unsigned long ret_addr)
-{
-       char *buf, *payload, *buf_end;
-       int ret;
-
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_EXIT);
-       /* FIXME: len=1024 */
-       ret = pack_msg_func_exit(payload, 1024, ret_type, regs, pt, sub_type,
-                                func_addr, ret_addr);
-       if (ret < 0)
-               goto put_buf;
-
-       buf_end = payload + ret;
-       set_len_msg(buf, buf_end);
-
-       ret = write_to_buffer(buf);
-
-put_buf:
-       put_current_buf();
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(exit_event);
-
-
-
-
-
-/* ============================================================================
- * =                            CONTEXT SWITCH                                =
- * ============================================================================
- */
-
-/*
- * @struct msg_context_switch
- * @brief Context switch message info.
- */
-struct msg_context_switch {
-       u64 pc_addr;            /**< Instruction pointer */
-       u32 pid;                /**< PID */
-       u32 tid;                /**< TID */
-       u32 cpu_num;            /**< CPU number */
-} __packed;
-
-static char *pack_msg_context_switch(char *payload, struct pt_regs *regs)
-{
-       struct msg_context_switch *mcs = (struct msg_context_switch *)payload;
-       struct task_struct *task = current;
-
-       mcs->pc_addr = 0;
-       mcs->pid = task->tgid;
-       mcs->tid = task->pid;
-       mcs->cpu_num = smp_processor_id();
-
-       return payload + sizeof(*mcs);
-}
-
-static int context_switch(struct pt_regs *regs, enum MSG_ID id)
-{
-       char *buf, *payload, *buf_end;
-       int ret;
-
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, id);
-       buf_end = pack_msg_context_switch(payload, regs);
-       set_len_msg(buf, buf_end);
-
-       ret = write_to_buffer(buf);
-       put_current_buf();
-
-       return ret;
-}
-
-/**
- * @brief Packs and writes context switch entry message.
- *
- * @param regs CPU register data.
- * @return Written data size on success, negative error code on error.
- */
-int switch_entry(struct pt_regs *regs)
-{
-       return context_switch(regs, MSG_CONTEXT_SWITCH_ENTRY);
-}
-EXPORT_SYMBOL_GPL(switch_entry);
-
-/**
- * @brief Packs and writes context switch exit message.
- *
- * @param regs CPU register data.
- * @return Written data size on success, negative error code on error.
- */
-int switch_exit(struct pt_regs *regs)
-{
-       return context_switch(regs, MSG_CONTEXT_SWITCH_EXIT);
-}
-EXPORT_SYMBOL_GPL(switch_exit);
-
-
-
-
-/* ============================================================================
- * =                                 ERROR                                    =
- * ============================================================================
- */
-
-/**
- * @struct msg_err
- * @brief Error message info.
- */
-struct msg_err {
-       char msg[0];            /**< Error message string */
-} __packed;
-
-static char *pack_msg_err(char *payload, const char *fmt, va_list args)
-{
-       struct msg_err *me = (struct msg_err *)payload;
-       int ret;
-
-       ret = vsprintf(me->msg, fmt, args);
-       if (ret < 0)
-               return payload;
-
-       return payload + sizeof(*me) + ret + 1;
-}
-
-/**
- * @brief Packs and writes error message.
- *
- * @param fmt Error string format
- * @return Written data size on success, negative error code on error.
- */
-int error_msg(const char *fmt, ...)
-{
-       char *buf, *payload, *buf_end;
-       va_list args;
-       int ret;
-
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, MSG_ERROR);
-
-       va_start(args, fmt);
-       buf_end = pack_msg_err(payload, fmt, args);
-       va_end(args);
-
-       set_len_msg(buf, buf_end);
-
-       ret = write_to_buffer(buf);
-       put_current_buf();
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(error_msg);
-
-
-
-
-
-/* ============================================================================
- * =                         MESSAGES FROM USER SPACE                         =
- * ============================================================================
- */
-
-/**
- * @brief Interface for writing messages from user space directly.
- *
- * @param buf Pointer to message.
- * @param len Message len.
- * @return len
- */
-int raw_msg(char *buf, size_t len)
-{
-       struct basic_msg_fmt *bmf = (struct basic_msg_fmt *)buf;
-
-       if (sizeof(*bmf) > len)
-               return -EINVAL;
-
-       if (bmf->len + sizeof(*bmf) != len)
-               return -EINVAL;
-
-       set_seq_num(bmf);
-       write_to_buffer(buf);
-
-       return len;
-}
-
-
-
-/* ============================================================================
- * =                              CUSTOM EVENT                                =
- * ============================================================================
- */
-
-static int pack_custom_event(char *buf, int len, const char *fmt, va_list args)
-{
-       enum { max_str_len = 512 };
-       const char *p;
-       char *buf_orig = buf;
-
-       for (p = fmt; *p != '\0'; p++) {
-               char ch = *p;
-
-               if (len < 1)
-                       return -ENOMEM;
-
-               *buf = tolower(ch);
-               buf += 1;
-               len -= 1;
-
-               switch (ch) {
-               case 'b': /* 1 byte(bool) */
-                       if (len < 1)
-                               return -ENOMEM;
-                       *buf = !!(char)va_arg(args, int);
-                       buf += 1;
-                       len -= 1;
-                       break;
-               case 'c': /* 1 byte(char) */
-                       if (len < 1)
-                               return -ENOMEM;
-                       *buf = (char)va_arg(args, int);
-                       buf += 1;
-                       len -= 1;
-                       break;
-               case 'f': /* 4 byte(float) */
-               case 'd': /* 4 byte(int) */
-                       if (len < 4)
-                               return -ENOMEM;
-                       *(u32 *)buf = va_arg(args, u32);
-                       buf += 4;
-                       len -= 4;
-                       break;
-               case 'x': /* 8 byte(long) */
-               case 'w': /* 8 byte(double) */
-                       if (len < 8)
-                               return -ENOMEM;
-                       *(u64 *)buf = va_arg(args, u64);
-                       buf += 8;
-                       len -= 8;
-                       break;
-               case 'p': /* 8 byte(pointer) */
-                       if (len < 8)
-                               return -ENOMEM;
-                       *(u64 *)buf = va_arg(args, unsigned long);
-                       buf += 8;
-                       len -= 8;
-                       break;
-               case 's': /* userspace string with '\0' terminating byte */
-               {
-                       const char __user *str;
-                       int len_s, n;
-
-                       str = va_arg(args, const char __user *);
-                       /* strnlen_user includes '\0' in its return value */
-                       len_s = strnlen_user(str, max_str_len);
-                       if (len < len_s)
-                               return -ENOMEM;
-                       /* strncpy_from_user returns the length of the copied
-                        * string (without '\0') */
-                       n = strncpy_from_user(buf, str, len_s - 1);
-                       if (n < 0)
-                               return n;
-                       buf[n] = '\0';
-
-                       buf += n + 1;
-                       len -= n + 1;
-                       break;
-               }
-               case 'S': /* kernelspace string with '\0' terminating byte */
-               {
-                       const char *str;
-                       int len_s;
-
-                       str = va_arg(args, const char *);
-                       len_s = strnlen(str, max_str_len);
-                       if (len < len_s + 1) /* + '\0' */
-                               return -ENOMEM;
-                       strncpy(buf, str, len_s);
-                       buf[len_s] = '\0';
-
-                       buf += len_s + 1;
-                       len -= len_s + 1;
-                       break;
-               }
-               case 'a': /* userspace byte array (len + ptr) */
-               {
-                       const void __user *ptr;
-                       u32 len_p, n;
-
-                       len_p = va_arg(args, u32);
-                       if (len < sizeof(len_p) + len_p)
-                               return -ENOMEM;
-                       *(u32 *)buf = len_p;
-                       buf += sizeof(len_p);
-                       len -= sizeof(len_p);
-
-                       ptr = va_arg(args, const void __user *);
-                       n = copy_from_user(buf, ptr, len_p);
-                       if (n < len_p)
-                               return -EFAULT;
-                       buf += len_p;
-                       len -= len_p;
-                       break;
-               }
-               case 'A': /* kernelspace byte array (len + ptr) */
-               {
-                       const void *ptr;
-                       u32 len_p;
-
-                       /* array size */
-                       len_p = va_arg(args, u32);
-                       if (len < sizeof(len_p) + len_p)
-                               return -ENOMEM;
-                       *(u32 *)buf = len_p;
-                       buf += sizeof(len_p);
-                       len -= sizeof(len_p);
-
-                       /* byte array */
-                       ptr = va_arg(args, const void *);
-                       memcpy(buf, ptr, len_p);
-                       buf += len_p;
-                       len -= len_p;
-                       break;
-               }
-               default:
-                       return -EINVAL;
-               }
-       }
-
-       return buf - buf_orig;
-}
-
-enum { max_custom_event_size = 2048 };
-
-/**
- * @brief Packs and writes custom entry event.
- *
- * @param func_addr Function address.
- * @param regs CPU register data.
- * @param type Probe type.
- * @param sub_type Probe sub type.
- * @param fmt Format string.
- * @return Written data size on success, negative error code on error.
- */
-int custom_entry_event(unsigned long func_addr, struct pt_regs *regs,
-                      int pt, int sub_type, const char *fmt, ...)
-{
-       char *buf, *payload, *args, *buf_end;
-       va_list vargs;
-       int ret;
-
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_ENTRY);
-       args = pack_msg_func_entry(payload, fmt, func_addr,
-                                  regs, pt, sub_type);
-
-       va_start(vargs, fmt);
-       ret = pack_custom_event(args, max_custom_event_size, fmt, vargs);
-       va_end(vargs);
-
-       if (ret < 0)
-               goto put_buf;
-
-       buf_end = args + ret;
-       set_len_msg(buf, buf_end);
-       ret = write_to_buffer(buf);
-
-put_buf:
-       put_current_buf();
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(custom_entry_event);
-
-/* TODO currently this function is a simple wrapper. it will be refactored when
- * protocol changes are applied */
-
-/**
- * @brief Packs and writes custom exit event.
- *
- * @param func_addr Function address.
- * @param ret_addr Return address.
- * @param regs CPU register data.
- * @param fmt Format string.
- * @return Written data size on success, negative error code on error.
- */
-int custom_exit_event(unsigned long func_addr, unsigned long ret_addr,
-                     struct pt_regs *regs, int pt, int sub_type,
-                     const char *fmt, ...)
-{
-       char *buf, *payload, *buf_end;
-       int ret;
-
-       buf = get_current_buf();
-       payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_EXIT);
-       ret = pack_msg_func_exit(payload, max_custom_event_size,
-                                fmt[0], regs, pt, sub_type,
-                                func_addr, ret_addr);
-       if (ret < 0)
-               goto put_buf;
-
-       buf_end = payload + ret;
-       set_len_msg(buf, buf_end);
-
-       ret = write_to_buffer(buf);
-
-put_buf:
-       put_current_buf();
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(custom_exit_event);
-
-
-
-
-
-/* ============================================================================
- * =                              WEB APP EVENT                               =
- * ============================================================================
- */
-
-/* TODO: develop method for obtaining this data during build... */
-/* location: webkit2-efl-123997_0.11.113/Source/WTF/wtf/text/StringImpl.h:70 */
-struct MStringImpl {
-       unsigned m_refCount;
-       unsigned m_length;
-       union {
-               const unsigned char *m_data8;
-               const unsigned short *m_data16;
-       };
-       union {
-               void *m_buffer;
-               struct MStringImpl *m_substringBuffer;
-               unsigned short *m_copyData16;
-       };
-       unsigned m_hashAndFlags;
-};
-
-/* location: webkit2-efl-123997_0.11.113/Source/JavaScriptCore/profiler/
- * CallIdentifier.h:36
- */
-struct MCallIdentifier {
-       struct MStringImpl *m_name;
-       struct MStringImpl *m_url;
-       unsigned m_lineNumber;
-};
-
-int entry_web_event(unsigned long func_addr, struct pt_regs *regs)
-{
-       char *buf, *pl;
-       long t;
-       int ret = 0, n, lnum;
-       struct MCallIdentifier *callIdentifier;
-       struct {
-               const char *str;
-               int len;
-       } m_name, m_url;
-       struct task_struct *task = current;
-
-       if (!check_event(current))
-               return 0;
-
-       callIdentifier = (void *)swap_get_uarg(regs, 2);
-
-       if (get_user(t, (int *)&callIdentifier->m_name) ||
-           get_user(m_name.str, &((struct MStringImpl *)t)->m_data8) ||
-           get_user(m_name.len, &((struct MStringImpl *)t)->m_length) ||
-           get_user(t, (int *)&callIdentifier->m_url) ||
-           get_user(m_url.str, &((struct MStringImpl *)t)->m_data8) ||
-           get_user(m_url.len, &((struct MStringImpl *)t)->m_length) ||
-           get_user(lnum, (int *)&callIdentifier->m_lineNumber)) {
-               print_err("%s: cannot read user memory\n", __func__);
-               return 0;
-       }
-
-       buf = get_current_buf();
-       pl = pack_basic_msg_fmt(buf, MSG_WEB_FUNCTION_ENTRY);
-
-       /* Pack message */
-       /* PID */
-       *(u32 *)pl = task->tgid;
-       pl += sizeof(u32);
-       /* TID */
-       *(u32 *)pl = task->pid;
-       pl += sizeof(u32);
-       /* Line number (in source file) */
-       *(u32 *)pl = lnum;
-       pl += sizeof(u32);
-       /* Function name */
-       n = strncpy_from_user(pl, m_name.str, m_name.len);
-       if (n < 0) {
-               print_err("%s: cannot read user memory (function name)\n",
-                         __func__);
-               goto put_current_buf_return;
-       } else {
-               pl[n] = '\0';
-               pl += n + 1;
-       }
-       /* URL (source file) */
-       n = strncpy_from_user(pl, m_url.str, m_url.len);
-       if (n < 0) {
-               print_err("%s: cannot read user memory (url)\n", __func__);
-               goto put_current_buf_return;
-       } else {
-               pl[n] = '\0';
-               pl += n + 1;
-       }
-
-       set_len_msg(buf, pl);
-       ret = write_to_buffer(buf);
-
-put_current_buf_return:
-       put_current_buf();
-       return ret;
-}
-EXPORT_SYMBOL_GPL(entry_web_event);
-
-int exit_web_event(unsigned long func_addr, struct pt_regs *regs)
-{
-       char *buf, *pl;
-       long t;
-       int ret = 0, n;
-       struct MCallIdentifier *callIdentifier;
-       struct {
-               const char *str;
-               int len;
-       } m_name;
-       struct task_struct *task = current;
-
-       if (!check_event(current))
-               return 0;
-
-       callIdentifier = (void *)swap_get_uarg(regs, 2);
-
-       if (get_user(t, (int *)&callIdentifier->m_name) ||
-           get_user(m_name.str, &((struct MStringImpl *)t)->m_data8) ||
-           get_user(m_name.len, &((struct MStringImpl *)t)->m_length)) {
-               print_err("%s: cannot read user memory\n", __func__);
-               return 0;
-       }
-
-       buf = get_current_buf();
-       pl = pack_basic_msg_fmt(buf, MSG_WEB_FUNCTION_EXIT);
-
-       /* Pack message */
-       /* PID */
-       *(u32 *)pl = task->tgid;
-       pl += sizeof(u32);
-       /* TID */
-       *(u32 *)pl = task->pid;
-       pl += sizeof(u32);
-       /* Function name */
-       n = strncpy_from_user(pl, m_name.str, m_name.len);
-       if (n < 0) {
-               print_err("%s: cannot read user memory (function name)\n",
-                         __func__);
-               goto put_current_buf_return;
-       } else {
-               pl[n] = '\0';
-               pl += n + 1;
-       }
-
-       set_len_msg(buf, pl);
-       ret = write_to_buffer(buf);
-
-put_current_buf_return:
-       put_current_buf();
-       return ret;
-}
-EXPORT_SYMBOL_GPL(exit_web_event);
-
-
-
-
 
-SWAP_LIGHT_INIT_MODULE(NULL, event_filter_init, event_filter_exit,
+SWAP_LIGHT_INIT_MODULE(NULL, core_init, core_exit,
                       init_debugfs_writer, exit_debugfs_writer);
 
 MODULE_LICENSE("GPL");
diff --git a/writer/swap_writer_module.h b/writer/swap_writer_module.h
deleted file mode 100644 (file)
index 38f2288..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * @file writer/swap_writer_module.h
- * @author Alexander Aksenov <a.aksenov@samsung.com>
- * @author Vyacheslav Cherkashin
- *
- * @section LICENSE
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * @section COPYRIGHT
- *
- * Copyright (C) Samsung Electronics, 2013
- *
- * @section DESCRIPTION
- *
- * Write module interface defenition.
- */
-
-#ifndef _SWAP_MSG_H
-#define _SWAP_MSG_H
-
-#include <linux/types.h>
-
-/**
- * @enum PROBE_TYPE
- * @brief Probe types.
- */
-enum PROBE_TYPE {
-       PT_US   = 1,            /**< User probe */
-       PT_KS   = 3             /**< Kernel probe */
-};
-
-/**
- * @enum PROBE_SUB_TYPE
- * @brief Probe sub types.
- */
-enum PROBE_SUB_TYPE {
-       PST_NONE        = 0x00,     /**< Common */
-       PST_KS_FILE     = 0x01,     /**< File feature */
-       PST_KS_IPC      = 0x02,     /**< Ipc feature */
-       PST_KS_PROCESS  = 0x04, /**< Process feature */
-       PST_KS_SIGNAL   = 0x08, /**< Signal feature */
-       PST_KS_NETWORK  = 0x10, /**< Network feature */
-       PST_KS_DESC     = 0x20      /**< Desc feature */
-};
-
-struct pt_regs;
-struct dentry;
-struct task_struct;
-struct vm_area_struct;
-
-int init_msg(size_t buf_size);
-void uninit_msg(void);
-
-void reset_discarded(void);
-unsigned int get_discarded_count(void);
-void reset_seq_num(void);
-
-int proc_info_msg(struct task_struct *task, struct dentry *dentry);
-void terminate_msg(struct task_struct *task);
-void pcoc_map_msg(struct vm_area_struct *vma);
-void proc_unmap_msg(unsigned long start, unsigned long end);
-void proc_comm_msg(struct task_struct *task);
-int sample_msg(struct pt_regs *regs);
-
-int entry_event(const char *fmt, unsigned long func_addr, struct pt_regs *regs,
-               enum PROBE_TYPE pt, int sub_type);
-int exit_event(char ret_type, struct pt_regs *regs, int pt, int sub_type,
-              unsigned long func_addr, unsigned long ret_addr);
-
-int entry_web_event(unsigned long func_addr, struct pt_regs *regs);
-int exit_web_event(unsigned long func_addr, struct pt_regs *regs);
-
-int switch_entry(struct pt_regs *regs);
-int switch_exit(struct pt_regs *regs);
-
-int error_msg(const char *fmt, ...);
-
-int raw_msg(char *buf, size_t len);
-
-int custom_entry_event(unsigned long func_addr, struct pt_regs *regs,
-                      int pt, int sub_type, const char *fmt, ...);
-int custom_exit_event(unsigned long func_addr, unsigned long ret_addr,
-                     struct pt_regs *regs, int pt, int sub_type,
-                     const char *fmt, ...);
-
-#endif /* _SWAP_MSG_H */