fbiprobe/ \
wsp/ \
nsp/ \
- task_ctx/
+ task_ctx/ \
+ uihv/
#ifndef __LOADER__
#define __LOADER__
-#define LOADER_PREFIX "SWAP_LOADER: "
-#define LOADER_MAX_ATTEMPTS 10
-#define LOADER_DEFAULT_PERMS (S_IRUSR | S_IWUSR) /* u+rw */
+struct pd_t;
+struct hd_t;
+struct uretprobe;
+struct uretprobe_instance;
+
+/* process loader states */
+enum ps_t {
+ NOT_LOADED,
+ LOADING,
+ LOADED,
+ FAILED,
+ ERROR
+};
+
+void loader_module_prepare_ujump(struct uretprobe_instance *ri,
+ struct pt_regs *regs, unsigned long addr);
+
+unsigned long loader_not_loaded_entry(struct uretprobe_instance *ri,
+ struct pt_regs *regs, struct pd_t *pd,
+ struct hd_t *hd);
+void loader_loading_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
+ struct pd_t *pd, struct hd_t *hd);
+void loader_failed_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
+ struct pd_t *pd, struct hd_t *hd);
+
+void loader_set_rp_data_size(struct uretprobe *rp);
+void loader_set_priv_origin(struct uretprobe_instance *ri, unsigned long addr);
+unsigned long loader_get_priv_origin(struct uretprobe_instance *ri);
+int loader_add_handler(char *path);
+
+
+struct pd_t *lpd_get(struct sspt_proc *proc);
+struct hd_t *lpd_get_hd(struct pd_t *pd, struct dentry *dentry);
+struct dentry *lpd_get_dentry(struct hd_t *hd);
+struct pd_t *lpd_get_parent_pd(struct hd_t *hd);
+enum ps_t lpd_get_state(struct hd_t *hd);
+unsigned long lpd_get_handlers_base(struct hd_t *hd);
+void *lpd_get_handle(struct hd_t *hd);
+long lpd_get_attempts(struct hd_t *hd);
+void lpd_dec_attempts(struct hd_t *hd);
#endif /* __LOADER__ */
#include <linux/spinlock.h>
#include <linux/limits.h>
#include <linux/list.h>
-
-#include "loader.h"
+#include "loader_defs.h"
#include "loader_control.h"
#include "loader_module.h"
#include <linux/limits.h>
#include <asm/uaccess.h>
#include <master/swap_debugfs.h>
-#include "loader.h"
+#include "loader_defs.h"
#include "loader_debugfs.h"
#include "loader_module.h"
#include "loader_control.h"
--- /dev/null
+#ifndef __LOADER_DEFS_H__
+#define __LOADER_DEFS_H__
+
+#define LOADER_PREFIX "SWAP_LOADER: "
+#define LOADER_MAX_ATTEMPTS 10
+#define LOADER_DEFAULT_PERMS (S_IRUSR | S_IWUSR) /* u+rw */
+
+#endif /* __LOADER_DEFS_H__ */
#include <us_manager/callbacks.h>
#include <writer/kernel_operations.h>
#include <master/swap_initializer.h>
-#include "loader.h"
+#include "loader_defs.h"
#include "loader_debugfs.h"
#include "loader_module.h"
+#include "loader.h"
#include "loader_storage.h"
#include "loader_control.h"
#include "loader_pd.h"
#include <linux/types.h>
struct dentry;
-struct pd_t;
-struct hd_t;
-struct uretprobe;
-struct uretprobe_instance;
bool loader_module_is_ready(void);
bool loader_module_is_running(void);
struct dentry *get_dentry(const char *filepath);
void put_dentry(struct dentry *dentry);
-void loader_module_prepare_ujump(struct uretprobe_instance *ri,
- struct pt_regs *regs, unsigned long addr);
-
-unsigned long loader_not_loaded_entry(struct uretprobe_instance *ri,
- struct pt_regs *regs, struct pd_t *pd,
- struct hd_t *hd);
-void loader_loading_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
- struct pd_t *pd, struct hd_t *hd);
-void loader_failed_ret(struct uretprobe_instance *ri, struct pt_regs *regs,
- struct pd_t *pd, struct hd_t *hd);
-
-void loader_set_rp_data_size(struct uretprobe *rp);
-void loader_set_priv_origin(struct uretprobe_instance *ri, unsigned long addr);
-unsigned long loader_get_priv_origin(struct uretprobe_instance *ri);
-int loader_add_handler(char *path);
#endif /* __LOADER_MODULE_H__ */
#include <us_manager/us_manager_common.h>
#include <us_manager/sspt/sspt_proc.h>
#include "loader_pd.h"
+#include "loader.h"
#include "loader_debugfs.h"
#include "loader_storage.h"
-#include "loader.h"
+#include "loader_defs.h"
struct pd_t {
unsigned long loader_base;
struct dentry;
struct list_head;
-/* process loader states */
-enum ps_t {
- NOT_LOADED,
- LOADING,
- LOADED,
- FAILED,
- ERROR
-};
-
-struct pd_t *lpd_get(struct sspt_proc *proc);
+
unsigned long lpd_get_loader_base(struct pd_t *pd);
void lpd_set_loader_base(struct pd_t *pd, unsigned long vaddr);
-struct hd_t *lpd_get_hd(struct pd_t *pd, struct dentry *dentry);
-struct dentry *lpd_get_dentry(struct hd_t *hd);
-struct pd_t *lpd_get_parent_pd(struct hd_t *hd);
-enum ps_t lpd_get_state(struct hd_t *hd);
void lpd_set_state(struct hd_t *hd, enum ps_t state);
-unsigned long lpd_get_handlers_base(struct hd_t *hd);
void lpd_set_handlers_base(struct hd_t *hd, unsigned long vaddr);
-void *lpd_get_handle(struct hd_t *hd);
void lpd_set_handle(struct hd_t *hd, void __user *handle);
-long lpd_get_attempts(struct hd_t *hd);
-void lpd_dec_attempts(struct hd_t *hd);
char __user *lpd_get_path(struct pd_t *pd, struct hd_t *hd);
#include <linux/fs.h>
#include <linux/list.h>
#include <ks_features/ks_map.h>
-#include "loader.h"
+#include "loader_defs.h"
#include "loader_module.h"
#include "loader_storage.h"
install -m 666 webprobe/swap_webprobe.ko -t %{buildroot}/opt/swap/sdk
install -m 666 loader/swap_loader.ko -t %{buildroot}/opt/swap/sdk
install -m 666 preload/swap_preload.ko -t %{buildroot}/opt/swap/sdk
+install -m 666 uihv/swap_uihv.ko -t %{buildroot}/opt/swap/sdk
install -m 666 fbiprobe/swap_fbiprobe.ko -t %{buildroot}/opt/swap/sdk
install -m 666 wsp/swap_wsp.ko -t %{buildroot}/opt/swap/sdk
install -m 666 nsp/swap_nsp.ko -t %{buildroot}/opt/swap/sdk
/opt/swap/sdk/swap_webprobe.ko
/opt/swap/sdk/swap_loader.ko
/opt/swap/sdk/swap_preload.ko
+/opt/swap/sdk/swap_uihv.ko
/opt/swap/sdk/swap_fbiprobe.ko
/opt/swap/sdk/swap_wsp.ko
/opt/swap/sdk/swap_nsp.ko
static const char PRELOAD_BINARIES_ADD[] = "bins_add";
static const char PRELOAD_BINARIES_REMOVE[] = "bins_remove";
-
static struct dentry *preload_root;
static struct dentry *target_list = NULL;
static struct dentry *target_add = NULL;
#include <us_manager/sspt/sspt_ip.h>
#include <us_manager/sspt/sspt_page.h>
#include <us_manager/sspt/sspt_file.h>
-#include <loader/loader_pd.h>
-#include <loader/loader_module.h>
+#include <loader/loader.h>
#include <master/swap_initializer.h>
#include "preload.h"
#include "preload_module.h"
if (hd == NULL)
goto out_set_orig;
- if ((flags & HANDLER_RUNNING) ||
- pt_check_disabled_probe(current, ip->orig_addr))
- goto out_set_orig;
-
if (lpd_get_state(hd) == NOT_LOADED ||
lpd_get_state(hd) == FAILED)
vaddr = loader_not_loaded_entry(ri, regs, pd, hd);
return 0;
}
-
-
-
-
-
-
-
-
static int get_caller_handler(struct uprobe *p, struct pt_regs *regs)
{
unsigned long caller;
return ret;
ret = swap_register_probe_type(SWAP_WRITE_MSG, &write_msg_iface);
+
return ret;
}
--- /dev/null
+EXTRA_CFLAGS := $(extra_cflags)
+
+obj-m := swap_uihv.o
+swap_uihv-y := uihv_module.o \
+ uihv_debugfs.o
--- /dev/null
+#ifndef __UIHV_H__
+#define __UIHV_H__
+
+#define UIHV_PREFIX "SWAP_UIHV: "
+#define UIHV_DEFAULT_PERMS (S_IRUSR | S_IWUSR) /* u+rw */
+
+#endif /* __UIHV_H__ */
--- /dev/null
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <asm/uaccess.h>
+#include <master/swap_debugfs.h>
+#include "uihv.h"
+#include "uihv_module.h"
+
+static const char UIHV_FOLDER[] = "uihv";
+static const char UIHV_PATH[] = "path";
+static const char UIHV_APP_INFO[] = "app_info";
+
+static struct dentry *uihv_root;
+
+
+
+/* ===========================================================================
+ * = UI VIEWER PATH =
+ * ===========================================================================
+ */
+
+
+static ssize_t uihv_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 uihv_path_write_out;
+ }
+
+ if (copy_from_user(path, buf, len)) {
+ ret = -EINVAL;
+ goto uihv_path_write_out;
+ }
+
+ path[len - 1] = '\0';
+
+ if (uihv_set_handler(path) != 0) {
+ printk(UIHV_PREFIX "Cannot set ui viewer path %s\n", path);
+ ret = -EINVAL;
+ goto uihv_path_write_out;
+ }
+
+ ret = len;
+
+ printk(UIHV_PREFIX "Set ui viewer path %s\n", path);
+
+uihv_path_write_out:
+ kfree(path);
+
+ return ret;
+}
+
+static const struct file_operations uihv_path_file_ops = {
+ .owner = THIS_MODULE,
+ .write = uihv_path_write,
+};
+
+
+/*
+ * format:
+ * main:app_path
+ *
+ * sample:
+ * 0x00000d60:/bin/app_sample
+ */
+static int uihv_add_app_info(const char *buf, size_t len)
+{
+ int n, ret;
+ char *app_path;
+ unsigned long main_addr;
+ const char fmt[] = "%%lx:/%%%ds";
+ char fmt_buf[64];
+
+ n = snprintf(fmt_buf, sizeof(fmt_buf), fmt, PATH_MAX - 2);
+ if (n <= 0)
+ return -EINVAL;
+
+ app_path = kmalloc(PATH_MAX, GFP_KERNEL);
+ if (app_path == NULL)
+ return -ENOMEM;
+
+ n = sscanf(buf, fmt_buf, &main_addr, app_path + 1);
+ if (n != 2) {
+ ret = -EINVAL;
+ goto free_app_path;
+ }
+ app_path[0] = '/';
+
+ printk(UIHV_PREFIX "Set ui viewer app path %s, main offset 0x%lx\n", app_path, main_addr);
+
+ ret = uihv_data_set(app_path, main_addr);
+
+free_app_path:
+ kfree(app_path);
+ return ret;
+}
+
+static ssize_t write_uihv_app_info(struct file *file,
+ const char __user *user_buf,
+ size_t len, loff_t *ppos)
+{
+ ssize_t ret;
+ char *buf;
+
+ buf = kmalloc(len, GFP_KERNEL);
+ if (buf == NULL) {
+ ret = -ENOMEM;
+ goto free_buf;
+ }
+
+ if (copy_from_user(buf, user_buf, len)) {
+ ret = -EINVAL;
+ goto free_buf;
+ }
+
+ buf[len - 1] = '\0';
+
+ if (uihv_add_app_info(buf, len))
+ ret = -EINVAL;
+
+free_buf:
+ kfree(buf);
+
+ return ret;
+}
+
+static const struct file_operations uihv_app_info_file_ops = {
+ .owner = THIS_MODULE,
+ .write = write_uihv_app_info,
+};
+
+
+int uihv_dfs_init(void)
+{
+ struct dentry *swap_dentry, *root, *path, *app_info;
+ 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(UIHV_FOLDER, swap_dentry);
+ if (IS_ERR_OR_NULL(root))
+ goto fail;
+
+ uihv_root = root;
+
+ path = debugfs_create_file(UIHV_PATH, UIHV_DEFAULT_PERMS, root,
+ NULL, &uihv_path_file_ops);
+ if (IS_ERR_OR_NULL(path)) {
+ ret = -ENOMEM;
+ goto remove;
+ }
+
+ app_info = debugfs_create_file(UIHV_APP_INFO, UIHV_DEFAULT_PERMS,
+ root, NULL, &uihv_app_info_file_ops);
+ if (IS_ERR_OR_NULL(app_info)) {
+ ret = -ENOMEM;
+ goto remove;
+ }
+
+ return 0;
+
+remove:
+ debugfs_remove_recursive(root);
+
+fail:
+ printk(UIHV_PREFIX "Debugfs initialization failure: %d\n", ret);
+
+ return ret;
+}
+
+void uihv_dfs_exit(void)
+{
+ if (uihv_root)
+ debugfs_remove_recursive(uihv_root);
+
+ uihv_root = NULL;
+}
--- /dev/null
+#ifndef __UIHV_DEBUGFS_H__
+#define __UIHV_DEBUGFS_H__
+
+int uihv_dfs_init(void);
+void uihv_dfs_exit(void);
+
+#endif /* __UIHV_DEBUGFS_H__ */
--- /dev/null
+#include <linux/namei.h>
+#include <us_manager/us_manager_common.h>
+#include <us_manager/pf/pf_group.h>
+#include <us_manager/sspt/sspt_page.h>
+#include <us_manager/sspt/sspt_file.h>
+#include <us_manager/sspt/sspt_proc.h>
+#include <us_manager/sspt/sspt_ip.h>
+#include <us_manager/callbacks.h>
+#include <us_manager/probes/probe_info_new.h>
+#include <writer/kernel_operations.h>
+#include <master/swap_initializer.h>
+#include <writer/swap_msg.h>
+#include <loader/loader.h>
+#include "uihv.h"
+#include "uihv_module.h"
+#include "uihv_debugfs.h"
+
+#define page_to_proc(page) ((page)->file->proc)
+#define ip_to_proc(ip) page_to_proc((ip)->page)
+#define urp_to_ip(rp) container_of(rp, struct sspt_ip, retprobe)
+
+static struct dentry *uihv_dentry = NULL;
+
+static inline struct pd_t *__get_process_data(struct uretprobe *rp)
+{
+ struct sspt_ip *ip = urp_to_ip(rp);
+ struct sspt_proc *proc = ip_to_proc(ip);
+
+ return lpd_get(proc);
+}
+
+
+/* ============================================================================
+ * = ui_viewer =
+ * ============================================================================
+ */
+
+/* main handler for ui viewer */
+static int uihv_main_eh(struct uretprobe_instance *ri, struct pt_regs *regs);
+static int uihv_main_rh(struct uretprobe_instance *ri, struct pt_regs *regs);
+static struct probe_desc pin_main = MAKE_URPROBE(uihv_main_eh,
+ uihv_main_rh, 0);
+
+struct ui_viewer_data {
+ struct dentry *app_dentry;
+ struct probe_new p_main;
+ struct pf_group *pfg;
+};
+
+static struct ui_viewer_data __ui_data;
+
+static int uihv_data_inst(void)
+{
+ int ret;
+ struct pf_group *pfg;
+
+ pfg = get_pf_group_by_dentry(__ui_data.app_dentry,
+ (void *)__ui_data.app_dentry);
+ if (pfg == NULL)
+ return -ENOMEM;
+
+ ret = pin_register(&__ui_data.p_main, pfg, __ui_data.app_dentry);
+ if (ret)
+ goto put_g;
+
+ __ui_data.pfg = pfg;
+
+ return 0;
+put_g:
+ put_pf_group(pfg);
+ return ret;
+}
+
+
+
+struct dentry *get_dentry(const char *filepath)
+{
+ struct path path;
+ struct dentry *dentry = NULL;
+
+ if (kern_path(filepath, LOOKUP_FOLLOW, &path) == 0) {
+ dentry = dget(path.dentry);
+ path_put(&path);
+ }
+
+ return dentry;
+}
+
+void put_dentry(struct dentry *dentry)
+{
+ dput(dentry);
+}
+
+int uihv_data_set(const char *app_path, unsigned long main_addr)
+{
+ struct dentry *dentry;
+
+ dentry = dentry_by_path(app_path);
+ if (dentry == NULL)
+ return -ENOENT;
+
+ __ui_data.app_dentry = dentry;
+ __ui_data.p_main.desc = &pin_main;
+ __ui_data.p_main.offset = main_addr;
+ __ui_data.pfg = NULL;
+
+ return uihv_data_inst();
+}
+
+int uihv_set_handler(char *path)
+{
+ struct dentry *dentry;
+ int ret;
+
+ if (uihv_dentry != NULL)
+ put_dentry(uihv_dentry);
+
+ dentry = get_dentry(path);
+ if (dentry == NULL) {
+ printk(KERN_WARNING UIHV_PREFIX "Error! Cannot get handler %s\n",
+ path);
+ return -EINVAL;
+ }
+
+ ret = loader_add_handler(path);
+ if (ret != 0)
+ return ret;
+
+ uihv_dentry = dentry;
+
+ return 0;
+}
+
+
+
+/* ============================================================================
+ * = ui viewer handlers =
+ * ============================================================================
+ */
+static int uihv_main_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
+{
+ struct pd_t *pd = __get_process_data(ri->rp);
+ struct hd_t *hd;
+ unsigned long old_pc = swap_get_instr_ptr(regs);
+ unsigned long vaddr = 0;
+
+ if (uihv_dentry == NULL)
+ return 0;
+
+ hd = lpd_get_hd(pd, uihv_dentry);
+ if (hd == NULL)
+ return 0;
+
+ if (lpd_get_state(hd) == NOT_LOADED)
+ vaddr = loader_not_loaded_entry(ri, regs, pd, hd);
+
+ loader_set_priv_origin(ri, vaddr);
+
+ /* PC change check */
+ return old_pc != swap_get_instr_ptr(regs);
+}
+
+static int uihv_main_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
+{
+ struct pd_t *pd = __get_process_data(ri->rp);
+ struct hd_t *hd;
+
+ if (uihv_dentry == NULL)
+ return 0;
+
+ hd = lpd_get_hd(pd, uihv_dentry);
+ if (hd == NULL)
+ return 0;
+
+ if (lpd_get_state(hd) == LOADING)
+ loader_loading_ret(ri, regs, pd, hd);
+
+ return 0;
+}
+
+static int uihv_init(void)
+{
+ int ret;
+
+ ret = uihv_dfs_init();
+
+ return ret;
+}
+
+static void uihv_exit(void)
+{
+ if (uihv_dentry != NULL)
+ put_dentry(uihv_dentry);
+}
+
+SWAP_LIGHT_INIT_MODULE(NULL, uihv_init, uihv_exit, NULL, NULL);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SWAP UI Hierarchy Viewer");
+MODULE_AUTHOR("Alexander Aksenov <a.aksenov@samsung.com>, Anastasia Lypa");
--- /dev/null
+#ifndef __UIHV_MODULE_H__
+#define __UIHV_MODULE_H__
+
+int uihv_data_set(const char *app_path, unsigned long main_addr);
+int uihv_set_handler(char *path);
+
+#endif /* __UIHV_MODULE_H__ */
ip->retprobe.handler = urp_ret_handler;
ip->retprobe.maxactive = 0;
/* FIXME: make dynamic size field 'data_size' */
- ip->retprobe.data_size = sizeof(void *);
+ ip->retprobe.data_size = 128;
}
static void urp_uninit(struct sspt_ip *ip)