Merge branch 'tizen_2.4' into 'tizen_2.4_dev' 36/38736/2
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 27 Apr 2015 12:22:12 +0000 (15:22 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Mon, 27 Apr 2015 12:24:02 +0000 (15:24 +0300)
Change-Id: I1133d65cd7fe8b74e084b4ea9e0bdc8fb470659d
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
1  2 
Kbuild
kprobe/arch/arm/swap-asm/swap_kprobes.h
packaging/swap-modules.spec
parser/msg_cmd.c
parser/msg_cmd.h
parser/swap_msg_parser.c
preload/preload_debugfs.c
uprobe/swap_uprobes.c
writer/swap_writer_module.c

diff --cc Kbuild
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index d9b4d18,0000000..8af94bb
mode 100644,000000..100644
--- /dev/null
@@@ -1,493 -1,0 +1,493 @@@
- #include <driver/swap_debugfs.h>
 +#include <linux/kernel.h>
 +#include <linux/debugfs.h>
 +#include <linux/err.h>
 +#include <linux/fs.h>
 +#include <linux/module.h>
 +#include <linux/slab.h>
 +#include <linux/mutex.h>
 +#include <linux/limits.h>
 +#include <asm/uaccess.h>
-       swap_dentry = get_swap_debugfs_dir();
++#include <master/swap_debugfs.h>
 +#include "preload.h"
 +#include "preload_debugfs.h"
 +#include "preload_module.h"
 +#include "preload_control.h"
 +#include "preload_patcher.h"
 +#include "preload_storage.h"
 +
 +static const char PRELOAD_FOLDER[] = "preload";
 +static const char PRELOAD_LOADER[] = "loader";
 +static const char PRELOAD_LOADER_OFFSET[] = "loader_offset";
 +static const char PRELOAD_LOADER_PATH[] = "loader_path";
 +static const char PRELOAD_BINARIES[] = "target_binaries";
 +static const char PRELOAD_BINARIES_LIST[] = "bins_list";
 +static const char PRELOAD_BINARIES_ADD[] = "bins_add";
 +static const char PRELOAD_BINARIES_REMOVE[] = "bins_remove";
 +static const char PRELOAD_CALLER[] = "caller";
 +static const char PRELOAD_HANDLERS_PATH[] = "handlers_path";
 +static const char PRELOAD_LINKER_DATA[] = "linker";
 +static const char PRELOAD_LINKER_PATH[] = "linker_path";
 +static const char PRELOAD_LINKER_R_DEBUG_OFFSET[] = "r_debug_offset";
 +
 +struct loader_info {
 +      char *path;
 +      unsigned long offset;
 +      struct dentry *dentry;
 +};
 +
 +static struct dentry *preload_root;
 +static struct loader_info __loader_info = {
 +      .path = NULL,
 +      .offset = 0,
 +      .dentry = NULL
 +};
 +
 +static unsigned long r_debug_offset = 0;
 +static DEFINE_MUTEX(__dentry_lock);
 +
 +static inline void dentry_lock(void)
 +{
 +      mutex_lock(&__dentry_lock);
 +}
 +
 +static inline void dentry_unlock(void)
 +{
 +      mutex_unlock(&__dentry_lock);
 +}
 +
 +
 +static void set_loader_file(char *path)
 +{
 +      __loader_info.path = path;
 +      dentry_lock();
 +      __loader_info.dentry = get_dentry(__loader_info.path);
 +      dentry_unlock();
 +}
 +
 +struct dentry *preload_debugfs_get_loader_dentry(void)
 +{
 +      struct dentry *dentry;
 +
 +      dentry_lock();
 +      dentry = __loader_info.dentry;
 +      dentry_unlock();
 +
 +      return dentry;
 +}
 +
 +unsigned long preload_debugfs_get_loader_offset(void)
 +{
 +      /* TODO Think about sync */
 +      return __loader_info.offset;
 +}
 +
 +static void clean_loader_info(void)
 +{
 +      if (__loader_info.path != NULL)
 +              kfree(__loader_info.path);
 +
 +      dentry_lock();
 +      if (__loader_info.dentry != NULL)
 +              put_dentry(__loader_info.dentry);
 +      dentry_unlock();
 +}
 +
 +struct dentry *debugfs_create_ptr(const char *name, mode_t mode,
 +                                struct dentry *parent,
 +                                unsigned long *value)
 +{
 +      struct dentry *dentry;
 +
 +#if BITS_PER_LONG == 32
 +      dentry = debugfs_create_x32(name, mode, parent, (u32 *)value);
 +#elif BITS_PER_LONG == 64
 +      dentry = debugfs_create_x64(name, mode, parent, (u64 *)value);
 +#else
 +#error Unsupported BITS_PER_LONG value
 +#endif
 +
 +      return dentry;
 +}
 +
 +
 +/* ===========================================================================
 + * =                              LOADER PATH                                =
 + * ===========================================================================
 + */
 +
 +static ssize_t loader_path_write(struct file *file, const char __user *buf,
 +                          size_t len, loff_t *ppos)
 +{
 +      ssize_t ret;
 +      char *path;
 +
 +      if (preload_module_is_running())
 +              return -EBUSY;
 +
 +      clean_loader_info();
 +
 +      path = kmalloc(len, GFP_KERNEL);
 +      if (path == NULL) {
 +              ret = -ENOMEM;
 +              goto out;
 +      }
 +
 +      if (copy_from_user(path, buf, len)) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      path[len - 1] = '\0';
 +      set_loader_file(path);
 +      ret = len;
 +
 +out:
 +      return ret;
 +}
 +
 +
 +static const struct file_operations loader_path_file_ops = {
 +      .owner = THIS_MODULE,
 +      .write = loader_path_write,
 +};
 +
 +
 +/* ===========================================================================
 + * =                                BIN PATH                                 =
 + * ===========================================================================
 + */
 +
 +static ssize_t bin_add_write(struct file *file, const char __user *buf,
 +                         size_t len, loff_t *ppos)
 +{
 +      ssize_t ret;
 +      char *path;
 +
 +      path = kmalloc(len, GFP_KERNEL);
 +      if (path == NULL) {
 +              ret = -ENOMEM;
 +              goto bin_add_write_out;
 +      }
 +
 +      if (copy_from_user(path, buf, len)) {
 +              ret = -EINVAL;
 +              goto bin_add_write_out;
 +      }
 +
 +      path[len - 1] = '\0';
 +
 +      if (preload_control_add_instrumented_binary(path) != 0) {
 +              printk(PRELOAD_PREFIX "Cannot add binary %s\n", path);
 +              ret = -EINVAL;
 +              goto bin_add_write_out;
 +      }
 +
 +      ret = len;
 +
 +bin_add_write_out:
 +      kfree(path);
 +
 +      return ret;
 +}
 +
 +static ssize_t bin_remove_write(struct file *file, const char __user *buf,
 +                            size_t len, loff_t *ppos)
 +{
 +      ssize_t ret;
 +
 +      ret = preload_control_clean_instrumented_bins();
 +      if (ret != 0) {
 +              printk(PRELOAD_PREFIX "Error during clean!\n");
 +              ret = -EINVAL;
 +              goto bin_remove_write_out;
 +      }
 +
 +      ret = len;
 +
 +bin_remove_write_out:
 +      return ret;
 +}
 +
 +static ssize_t bin_list_read(struct file *file, char __user *usr_buf,
 +                               size_t count, loff_t *ppos)
 +{
 +      unsigned int i;
 +      unsigned int files_cnt = 0;
 +      ssize_t len = 0, tmp, ret = 0;
 +      char **filenames = NULL;
 +      char *buf = NULL;
 +      char *ptr = NULL;
 +
 +      files_cnt = preload_control_get_bin_names(&filenames);
 +
 +      if (files_cnt == 0) {
 +              printk(PRELOAD_PREFIX "Cannot read binaries names!\n");
 +              ret = 0;
 +              goto bin_list_read_out;
 +      }
 +
 +      for (i = 0; i < files_cnt; i++)
 +              len += strlen(filenames[i]);
 +
 +      buf = kmalloc(len + files_cnt, GFP_KERNEL);
 +      if (buf == NULL) {
 +              ret = 0;
 +              goto bin_list_read_fail;
 +      }
 +
 +      ptr = buf;
 +
 +      for (i = 0; i < files_cnt; i++) {
 +              tmp = strlen(filenames[i]);
 +              memcpy(ptr, filenames[i], tmp);
 +              ptr += tmp;
 +              *ptr = '\n';
 +              ptr += 1;
 +      }
 +
 +      preload_control_release_bin_names(&filenames);
 +
 +      return simple_read_from_buffer(usr_buf, count, ppos, buf, len);
 +
 +bin_list_read_fail:
 +      preload_control_release_bin_names(&filenames);
 +
 +bin_list_read_out:
 +      return ret;
 +}
 +
 +static const struct file_operations bin_list_file_ops = {
 +      .owner = THIS_MODULE,
 +      .read = bin_list_read
 +};
 +
 +static const struct file_operations bin_add_file_ops = {
 +      .owner = THIS_MODULE,
 +      .write = bin_add_write,
 +};
 +
 +static const struct file_operations bin_remove_file_ops = {
 +      .owner = THIS_MODULE,
 +      .write = bin_remove_write,
 +};
 +
 +
 +/* ===========================================================================
 + * =                            LINKER PATH                                  =
 + * ===========================================================================
 + */
 +
 +
 +static ssize_t linker_path_write(struct file *file, const char __user *buf,
 +                                size_t len, loff_t *ppos)
 +{
 +      ssize_t ret;
 +      char *path;
 +
 +      path = kmalloc(len, GFP_KERNEL);
 +      if (path == NULL) {
 +              ret = -ENOMEM;
 +              goto linker_path_write_out;
 +      }
 +
 +      if (copy_from_user(path, buf, len)) {
 +              ret = -EINVAL;
 +              goto linker_path_write_out;
 +      }
 +
 +      path[len - 1] = '\0';
 +
 +      if (preload_storage_set_linker_info(path) != 0) {
 +              printk(PRELOAD_PREFIX "Cannot set linker path %s\n", path);
 +              ret = -EINVAL;
 +              goto linker_path_write_out;
 +      }
 +
 +      ret = len;
 +
 +linker_path_write_out:
 +      kfree(path);
 +
 +      return ret;
 +}
 +
 +static const struct file_operations linker_path_file_ops = {
 +      .owner = THIS_MODULE,
 +      .write = linker_path_write,
 +};
 +
 +
 +/* ===========================================================================
 + * =                           HANDLERS PATH                                 =
 + * ===========================================================================
 + */
 +
 +
 +static ssize_t handlers_path_write(struct file *file, const char __user *buf,
 +                                 size_t len, loff_t *ppos)
 +{
 +      ssize_t ret;
 +      char *path;
 +
 +      path = kmalloc(len, GFP_KERNEL);
 +      if (path == NULL) {
 +              ret = -ENOMEM;
 +              goto handlers_path_write_out;
 +      }
 +
 +      if (copy_from_user(path, buf, len)) {
 +              ret = -EINVAL;
 +              goto handlers_path_write_out;
 +      }
 +
 +      path[len - 1] = '\0';
 +
 +      if (preload_storage_set_handlers_info(path) != 0) {
 +              printk(PRELOAD_PREFIX "Cannot set handler path %s\n", path);
 +              ret = -EINVAL;
 +              goto handlers_path_write_out;
 +      }
 +
 +      ret = len;
 +
 +handlers_path_write_out:
 +      kfree(path);
 +
 +      return ret;
 +}
 +
 +static const struct file_operations handlers_path_file_ops = {
 +      .owner = THIS_MODULE,
 +      .write = handlers_path_write,
 +};
 +
 +
 +
 +
 +unsigned long preload_debugfs_r_debug_offset(void)
 +{
 +      return r_debug_offset;
 +}
 +
 +int preload_debugfs_init(void)
 +{
 +      struct dentry *swap_dentry, *root, *loader, *open_p, *lib_path,
 +                *bin_path, *bin_list, *bin_add, *bin_remove,
 +                *linker_dir, *linker_path, *linker_offset, *handlers_path;
 +      int ret;
 +
 +      ret = -ENODEV;
 +      if (!debugfs_initialized())
 +              goto fail;
 +
 +      ret = -ENOENT;
++      swap_dentry = swap_debugfs_getdir();
 +      if (!swap_dentry)
 +              goto fail;
 +
 +      ret = -ENOMEM;
 +      root = debugfs_create_dir(PRELOAD_FOLDER, swap_dentry);
 +      if (IS_ERR_OR_NULL(root))
 +              goto fail;
 +
 +      preload_root = root;
 +
 +      loader = debugfs_create_dir(PRELOAD_LOADER, root);
 +      if (IS_ERR_OR_NULL(root)) {
 +              ret = -ENOMEM;
 +              goto remove;
 +      }
 +
 +      open_p = debugfs_create_ptr(PRELOAD_LOADER_OFFSET, PRELOAD_DEFAULT_PERMS,
 +                                  loader, &__loader_info.offset);
 +      if (IS_ERR_OR_NULL(open_p)) {
 +              ret = -ENOMEM;
 +              goto remove;
 +      }
 +
 +      lib_path = debugfs_create_file(PRELOAD_LOADER_PATH, PRELOAD_DEFAULT_PERMS,
 +                                     loader, NULL, &loader_path_file_ops);
 +      if (IS_ERR_OR_NULL(lib_path)) {
 +              ret = -ENOMEM;
 +              goto remove;
 +      }
 +
 +      bin_path = debugfs_create_dir(PRELOAD_BINARIES, root);
 +      if (IS_ERR_OR_NULL(bin_path)) {
 +              ret = -ENOMEM;
 +              goto remove;
 +      }
 +
 +      bin_list = debugfs_create_file(PRELOAD_BINARIES_LIST, PRELOAD_DEFAULT_PERMS,
 +                                     bin_path, NULL, &bin_list_file_ops);
 +      if (IS_ERR_OR_NULL(bin_list)) {
 +              ret = -ENOMEM;
 +              goto remove;
 +      }
 +
 +      bin_add = debugfs_create_file(PRELOAD_BINARIES_ADD, PRELOAD_DEFAULT_PERMS,
 +                                     bin_path, NULL, &bin_add_file_ops);
 +      if (IS_ERR_OR_NULL(bin_add)) {
 +              ret = -ENOMEM;
 +              goto remove;
 +      }
 +
 +      bin_remove = debugfs_create_file(PRELOAD_BINARIES_REMOVE,
 +                                       PRELOAD_DEFAULT_PERMS, bin_path, NULL,
 +                                       &bin_remove_file_ops);
 +      if (IS_ERR_OR_NULL(bin_remove)) {
 +              ret = -ENOMEM;
 +              goto remove;
 +      }
 +
 +      linker_dir = debugfs_create_dir(PRELOAD_LINKER_DATA, root);
 +      if (IS_ERR_OR_NULL(linker_dir)) {
 +              ret = -ENOMEM;
 +              goto remove;
 +      }
 +
 +      linker_path = debugfs_create_file(PRELOAD_LINKER_PATH,
 +                                        PRELOAD_DEFAULT_PERMS, linker_dir, NULL,
 +                                        &linker_path_file_ops);
 +      if (IS_ERR_OR_NULL(linker_path)) {
 +              ret = -ENOMEM;
 +              goto remove;
 +      }
 +
 +      linker_offset = debugfs_create_ptr(PRELOAD_LINKER_R_DEBUG_OFFSET,
 +                                         PRELOAD_DEFAULT_PERMS, linker_dir,
 +                                         &r_debug_offset);
 +      if (IS_ERR_OR_NULL(linker_offset)) {
 +              ret = -ENOMEM;
 +              goto remove;
 +      }
 +
 +      handlers_path = debugfs_create_file(PRELOAD_HANDLERS_PATH,
 +                                          PRELOAD_DEFAULT_PERMS, root, NULL,
 +                                          &handlers_path_file_ops);
 +      if (IS_ERR_OR_NULL(handlers_path)) {
 +              ret = -ENOMEM;
 +              goto remove;
 +      }
 +
 +      return 0;
 +
 +remove:
 +
 +      debugfs_remove_recursive(root);
 +
 +fail:
 +      printk(PRELOAD_PREFIX "Debugfs initialization failure: %d\n", ret);
 +
 +      return ret;
 +}
 +
 +void preload_debugfs_exit(void)
 +{
 +      if (preload_root)
 +              debugfs_remove_recursive(preload_root);
 +      preload_root = NULL;
 +
 +      preload_module_set_not_ready();
 +      clean_loader_info();
 +}
Simple merge
@@@ -1457,187 -1456,8 +1458,171 @@@ put_buf
  }
  EXPORT_SYMBOL_GPL(custom_exit_event);
  
- static int __init swap_writer_module_init(void)
- {
-       int ret;
 +
 +
 +
++
 +/* ============================================================================
 + * =                              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);
 +
-       ret = event_filter_init();
-       if (ret)
-               return ret;
 +
-       ret = init_debugfs_writer();
-       if (ret)
-               event_filter_exit();
 +
-       return ret;
- }
- static void __exit swap_writer_module_exit(void)
- {
-       exit_debugfs_writer();
-       event_filter_exit();
- }
 +
- module_init(swap_writer_module_init);
- module_exit(swap_writer_module_exit);
 +
+ SWAP_LIGHT_INIT_MODULE(NULL, event_filter_init, event_filter_exit,
+                      init_debugfs_writer, exit_debugfs_writer);
  
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("SWAP Writer module");