nsp_module.o \
nsp.o \
nsp_msg.o \
- nsp_tdata.o \
nsp_debugfs.o
#include <linux/module.h>
#include <writer/swap_msg.h>
+#include <kprobe/swap_ktd.h>
#include <uprobe/swap_uaccess.h>
#include <us_manager/pf/pf_group.h>
#include <us_manager/sspt/sspt_proc.h>
#include <us_manager/probes/probe_info_new.h>
#include "nsp.h"
#include "nsp_msg.h"
-#include "nsp_tdata.h"
#include "nsp_print.h"
#include "nsp_debugfs.h"
return -EINVAL;
__nsp_disabel();
- tdata_disable();
stat = NS_OFF;
static int set_stat_on(void)
{
- int ret;
-
if (is_init() == false)
return -EPERM;
if (stat == NS_ON)
return -EINVAL;
- ret = tdata_enable();
- if (ret)
- return ret;
-
__nsp_enable();
stat = NS_ON;
/* ============================================================================
+ * = tdata =
+ * ============================================================================
+ */
+enum nsp_proc_stat {
+ NPS_OPEN_E, /* mapping begin */
+ NPS_OPEN_R,
+ NPS_SYM_E,
+ NPS_SYM_R, /* mapping end */
+ NPS_MAIN_E, /* main begin */
+ NPS_AC_EFL_MAIN_E, /* main end */
+ NPS_AC_INIT_R, /* create begin */
+ NPS_ELM_RUN_E, /* create end */
+ NPS_DO_APP_E, /* reset begin */
+ NPS_DO_APP_R /* reset end */
+};
+
+struct tdata {
+ enum nsp_proc_stat stat;
+ struct nsp_data *nsp_data;
+ u64 time;
+ void __user *handle;
+ struct probe_new p_main;
+};
+
+
+static void ktd_init(struct task_struct *task, void *data)
+{
+ struct tdata *tdata = (struct tdata *)data;
+
+ tdata->nsp_data = NULL;
+}
+
+struct ktask_data ktd = {
+ .init = ktd_init,
+ .size = sizeof(struct tdata),
+};
+
+static struct tdata *tdata_get(struct task_struct *task)
+{
+ return (struct tdata *)swap_ktd(&ktd, task);
+}
+
+
+
+
+
+/* ============================================================================
* = handlers =
* ============================================================================
*/
nsp_data = nsp_data_find_by_path(path);
if (nsp_data) {
- struct task_struct *task = current;
- struct tdata *tdata;
-
- tdata = tdata_get(task);
- if (tdata) {
- nsp_print("ERROR: dlopen already cal for '%s'\n", path);
- tdata_put(tdata);
- goto free_path;
- }
+ struct tdata *tdata = tdata_get(current);
- tdata = tdata_create(task);
- if (tdata) {
+ /* init tdata */
+ if (tdata->nsp_data == NULL) {
tdata->stat = NPS_OPEN_E;
tdata->time = swap_msg_current_time();
tdata->nsp_data = nsp_data;
- tdata_put(tdata);
- } else {
- nsp_print("ERROR: out of memory\n");
}
}
-free_path:
kfree(path);
return 0;
}
static int dlopen_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
{
- struct tdata *tdata;
+ struct tdata *tdata = tdata_get(current);
+ void *handle = (void *)regs_return_value(regs);
- tdata = tdata_get(current);
- if (tdata) {
- void *handle;
-
- handle = (void *)regs_return_value(regs);
- if ((tdata->stat == NPS_OPEN_E) && handle) {
- tdata->stat = NPS_OPEN_R;
- tdata->handle = handle;
- tdata_put(tdata);
- } else {
- tdata_destroy(tdata);
- }
+ if ((tdata->stat == NPS_OPEN_E) && handle) {
+ tdata->stat = NPS_OPEN_R;
+ tdata->handle = handle;
+ } else {
+ tdata->handle = NULL;
}
return 0;
static int dlsym_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
{
- struct tdata *tdata;
+ struct tdata *tdata = tdata_get(current);
+ void __user *handle = (void __user *)swap_get_uarg(regs, 0);
+ const char __user *str = (const char __user *)swap_get_uarg(regs, 1);
- tdata = tdata_get(current);
- if (tdata) {
- const char __user *str = (char __user *)swap_get_uarg(regs, 1);
+ if (handle == tdata->handle && tdata->stat == NPS_OPEN_R) {
const char *name;
- void *handle;
- handle = (void *)swap_get_uarg(regs, 0);
- if (handle == tdata->handle && tdata->stat == NPS_OPEN_R) {
- name = strdup_from_user(str, GFP_ATOMIC);
- if (name && (strcmp(name, "main") == 0))
- tdata->stat = NPS_SYM_E;
+ name = strdup_from_user(str, GFP_ATOMIC);
+ if (name && (strcmp(name, "main") == 0))
+ tdata->stat = NPS_SYM_E;
- kfree(name);
- }
-
- tdata_put(tdata);
+ kfree(name);
}
return 0;
static int dlsym_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
{
- struct tdata *tdata;
+ struct tdata *tdata = tdata_get(current);
- tdata = tdata_get(current);
- if (tdata) {
- if (tdata->stat == NPS_SYM_E)
- tdata->stat = NPS_SYM_R;
- tdata_put(tdata);
- }
+ if (tdata->handle && tdata->stat == NPS_SYM_E)
+ tdata->stat = NPS_SYM_R;
return 0;
}
static void stage_begin(enum nsp_proc_stat priv, enum nsp_proc_stat cur)
{
- struct tdata *tdata;
+ struct tdata *tdata = tdata_get(current);
- tdata = tdata_get(current);
- if (tdata) {
- if (tdata->stat == priv) {
- tdata->stat = cur;
- tdata->time = swap_msg_current_time();
- }
-
- tdata_put(tdata);
+ if (tdata->handle && tdata->stat == priv) {
+ tdata->stat = cur;
+ tdata->time = swap_msg_current_time();
}
}
static void stage_end(enum nsp_proc_stat priv, enum nsp_proc_stat cur,
enum nsp_msg_stage st)
{
- struct tdata *tdata;
+ struct tdata *tdata = tdata_get(current);
u64 time_start;
u64 time_end;
- tdata = tdata_get(current);
- if (tdata) {
- if (tdata->stat != priv) {
- tdata_put(tdata);
- return;
- }
-
+ if (tdata->handle && tdata->stat == priv) {
tdata->stat = cur;
time_start = tdata->time;
- tdata_put(tdata);
time_end = swap_msg_current_time();
nsp_msg(st, time_start, time_end);
static int main_h(struct uprobe *p, struct pt_regs *regs)
{
- struct tdata *tdata;
+ struct tdata *tdata = tdata_get(current);
u64 time_start;
u64 time_end;
- tdata = tdata_get(current);
- if (tdata) {
- if (tdata->stat != NPS_SYM_R) {
- tdata_put(tdata);
- return 0;
- }
-
+ if (tdata->handle && tdata->stat == NPS_SYM_R) {
tdata->stat = NPS_MAIN_E;
time_start = tdata->time;
time_end = swap_msg_current_time();
tdata->time = time_end;
- tdata_put(tdata);
-
nsp_msg(NMS_MAPPING, time_start, time_end);
}
if (rp && get_quiet() == QT_OFF) {
struct us_ip *ip;
- char ret_type;
unsigned long func_addr;
unsigned long ret_addr;
ip = container_of(rp, struct us_ip, retprobe);
func_addr = (unsigned long)ip->orig_addr;
ret_addr = (unsigned long)ri->ret_addr;
- ret_type = ip->desc->info.rp_i.ret_type;
rp_msg_exit(regs, func_addr, 'n', ret_addr);
}
int nsp_init(void)
{
- return 0;
+ return swap_ktd_reg(&ktd);
}
void nsp_exit(void)
set_stat_off();
uninit_variables();
+ swap_ktd_unreg(&ktd);
}
#include <linux/module.h>
#include <master/swap_initializer.h>
#include "nsp.h"
-#include "nsp_tdata.h"
#include "nsp_debugfs.h"
-SWAP_LIGHT_INIT_MODULE(tdata_once, nsp_init, nsp_exit,
+SWAP_LIGHT_INIT_MODULE(NULL, nsp_init, nsp_exit,
nsp_debugfs_init, nsp_debugfs_exit);
MODULE_LICENSE("GPL");
+++ /dev/null
-/*
- * 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/list.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <writer/swap_msg.h>
-#include <kprobe/swap_kprobes.h>
-#include <ksyms/ksyms.h>
-#include "nsp_tdata.h"
-#include "nsp_print.h"
-
-
-/* ============================================================================
- * = priv_tdata =
- * ============================================================================
- */
-struct priv_tdata {
- struct list_head list;
- struct task_struct *task;
-
- struct tdata tdata;
-};
-
-
-static LIST_HEAD(task_list);
-static DEFINE_SPINLOCK(task_list_lock);
-
-
-/* called with task_list_lock held */
-static struct priv_tdata *priv_tdata_create(struct task_struct *task)
-{
- struct priv_tdata *p_tdata;
-
- p_tdata = kmalloc(sizeof(*p_tdata), GFP_ATOMIC);
- if (p_tdata) {
- INIT_LIST_HEAD(&p_tdata->list);
- p_tdata->task = task;
-
- /* add to list */
- list_add(&p_tdata->list, &task_list);
- }
-
- return p_tdata;
-}
-
-/* called with task_list_lock held */
-static void priv_tdata_destroy(struct priv_tdata *p_tdata)
-{
- /* delete from list */
- list_del(&p_tdata->list);
-
- kfree(p_tdata);
-}
-
-/* called with task_list_lock held */
-static void __priv_tdata_destroy(struct tdata *tdata)
-{
- struct priv_tdata *p_tdata;
-
- p_tdata = container_of(tdata, struct priv_tdata, tdata);
- priv_tdata_destroy(p_tdata);
-}
-
-/* called with task_list_lock held */
-static void priv_tdata_destroy_all(void)
-{
- struct priv_tdata *p_tdata, *n;
-
- list_for_each_entry_safe(p_tdata, n, &task_list, list)
- priv_tdata_destroy(p_tdata);
-}
-
-
-
-
-
-/* ============================================================================
- * = tdata =
- * ============================================================================
- */
-struct tdata *tdata_create(struct task_struct *task)
-{
- struct priv_tdata *p_tdata;
-
- spin_lock(&task_list_lock);
- p_tdata = priv_tdata_create(task);
- if (p_tdata)
- return &p_tdata->tdata;
- spin_unlock(&task_list_lock);
-
- return NULL;
-
-}
-
-void tdata_destroy(struct tdata *tdata)
-{
- __priv_tdata_destroy(tdata);
- spin_unlock(&task_list_lock);
-}
-
-struct tdata *tdata_find(struct task_struct *task)
-{
- struct priv_tdata *p_tdata;
-
- list_for_each_entry(p_tdata, &task_list, list) {
- if (p_tdata->task == task)
- return &p_tdata->tdata;
- }
-
- return NULL;
-}
-
-struct tdata *tdata_get(struct task_struct *task)
-{
- struct tdata *tdata;
-
- spin_lock(&task_list_lock);
- tdata = tdata_find(task);
- if (tdata)
- return tdata;
- spin_unlock(&task_list_lock);
-
- return NULL;
-}
-
-void tdata_put(struct tdata *tdata)
-{
- spin_unlock(&task_list_lock);
-}
-
-
-
-
-
-/* ============================================================================
- * = do_exit =
- * ============================================================================
- */
-static int do_exit_handler(struct kprobe *p, struct pt_regs *regs)
-{
- struct tdata *tdata;
-
- tdata = tdata_get(current);
- if (tdata)
- tdata_destroy(tdata);
-
- return 0;
-}
-
-struct kprobe do_exit_kp = {
- .pre_handler = do_exit_handler,
-};
-
-int tdata_enable(void)
-{
- int ret;
-
- ret = swap_register_kprobe(&do_exit_kp);
- if (ret)
- return ret;
-
- return ret;
-}
-
-void tdata_disable(void)
-{
- swap_unregister_kprobe(&do_exit_kp);
-
- spin_lock(&task_list_lock);
- priv_tdata_destroy_all();
- spin_unlock(&task_list_lock);
-}
-
-int tdata_once(void)
-{
- const char *sym;
-
- sym = "do_exit";
- do_exit_kp.addr = (void *)swap_ksyms(sym);
- if (do_exit_kp.addr == NULL)
- goto not_found;
-
- return 0;
-
-not_found:
- nsp_print("ERROR: symbol '%s' not found\n", sym);
- return -ESRCH;
-}
+++ /dev/null
-/*
- * 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 _NSP_TDATA_H
-#define _NSP_TDATA_H
-
-
-#include <linux/types.h>
-#include <us_manager/probes/probe_info_new.h>
-
-
-enum nsp_proc_stat {
- NPS_OPEN_E, /* mapping begin */
- NPS_OPEN_R,
- NPS_SYM_E,
- NPS_SYM_R, /* mapping end */
- NPS_MAIN_E, /* main begin */
- NPS_AC_EFL_MAIN_E, /* main end */
- NPS_AC_INIT_R, /* create begin */
- NPS_ELM_RUN_E, /* create end */
- NPS_DO_APP_E, /* reset begin */
- NPS_DO_APP_R /* reset end */
-};
-
-
-struct nsp_data;
-struct task_struct;
-
-
-struct tdata {
- enum nsp_proc_stat stat;
- struct nsp_data *nsp_data;
- u64 time;
- void *handle;
- struct probe_new p_main;
-};
-
-
-struct tdata *tdata_create(struct task_struct *task);
-void tdata_destroy(struct tdata *tdata);
-
-struct tdata *tdata_get(struct task_struct *task);
-void tdata_put(struct tdata *tdata);
-
-int tdata_enable(void);
-void tdata_disable(void);
-
-int tdata_once(void);
-
-
-#endif /* _NSP_TDATA_H */