2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * Copyright (C) Samsung Electronics, 2015
18 * 2015 Vyacheslav Cherkashin <v.cherkashin@samsung.com>
23 #include <linux/module.h>
24 #include <writer/swap_msg.h>
25 #include <uprobe/swap_uaccess.h>
26 #include <us_manager/pf/pf_group.h>
27 #include <us_manager/sspt/sspt_proc.h>
28 #include <us_manager/probes/probe_info_new.h>
31 #include "nsp_tdata.h"
32 #include "nsp_print.h"
33 #include "nsp_debugfs.h"
36 /* ============================================================================
38 * ============================================================================
42 static int dlopen_eh(struct uretprobe_instance *ri, struct pt_regs *regs);
43 static int dlopen_rh(struct uretprobe_instance *ri, struct pt_regs *regs);
44 static struct probe_info_new pin_dlopen = MAKE_URPROBE(dlopen_eh, dlopen_rh, 0);
45 static struct probe_new p_dlopen = {
50 static int dlsym_eh(struct uretprobe_instance *ri, struct pt_regs *regs);
51 static int dlsym_rh(struct uretprobe_instance *ri, struct pt_regs *regs);
52 static struct probe_info_new pin_dlsym = MAKE_URPROBE(dlsym_eh, dlsym_rh, 0);
53 static struct probe_new p_dlsym = {
58 static int main_eh(struct uretprobe_instance *ri, struct pt_regs *regs);
59 static int main_rh(struct uretprobe_instance *ri, struct pt_regs *regs);
60 static struct probe_info_new pin_main = MAKE_URPROBE(main_eh, main_rh, 0);
62 /* appcore_efl_main */
63 static int ac_efl_main_h(struct kprobe *p, struct pt_regs *regs);
64 static struct probe_info_new pin_ac_efl_main = MAKE_UPROBE(ac_efl_main_h);
65 static struct probe_new p_ac_efl_main = {
66 .info = &pin_ac_efl_main
69 /* appcore_init@plt */
70 static int ac_init_rh(struct uretprobe_instance *ri, struct pt_regs *regs);
71 static struct probe_info_new pin_ac_init = MAKE_URPROBE(NULL, ac_init_rh, 0);
72 static struct probe_new p_ac_init = {
77 static int elm_run_h(struct kprobe *p, struct pt_regs *regs);
78 static struct probe_info_new pin_elm_run = MAKE_UPROBE(elm_run_h);
79 static struct probe_new p_elm_run = {
84 static int do_app_eh(struct uretprobe_instance *ri, struct pt_regs *regs);
85 static int do_app_rh(struct uretprobe_instance *ri, struct pt_regs *regs);
86 static struct probe_info_new pin_do_app = MAKE_URPROBE(do_app_eh, do_app_rh, 0);
87 static struct probe_new p_do_app = {
95 /* ============================================================================
96 * = the variables are initialized by the user =
97 * ============================================================================
99 static const char *lpad_path;
100 static struct dentry *lpad_dentry;
102 static const char *libappcore_path;
103 static struct dentry *libappcore_dentry;
105 static void uninit_variables(void)
111 kfree(libappcore_path);
112 libappcore_path = NULL;
113 libappcore_dentry = NULL;
116 static bool is_init(void)
118 return lpad_dentry && libappcore_dentry;
121 static int do_set_lpad_info(const char *path, unsigned long dlopen,
124 struct dentry *dentry;
125 const char *new_path;
127 dentry = dentry_by_path(path);
128 if (dentry == NULL) {
129 pr_err("dentry not found (path='%s')\n", path);
133 new_path = kstrdup(path, GFP_KERNEL);
134 if (new_path == NULL) {
135 pr_err("out of memory\n");
141 lpad_path = new_path;
142 lpad_dentry = dentry;
143 p_dlopen.offset = dlopen;
144 p_dlsym.offset = dlsym;
149 static int do_set_appcore_info(struct appcore_info_data *info)
151 struct dentry *dentry;
152 const char *new_path;
154 dentry = dentry_by_path(info->path);
155 if (dentry == NULL) {
156 pr_err("dentry not found (path='%s')\n", info->path);
160 new_path = kstrdup(info->path, GFP_KERNEL);
161 if (new_path == NULL) {
162 pr_err("out of memory\n");
166 kfree(libappcore_path);
168 libappcore_path = new_path;
169 libappcore_dentry = dentry;
170 p_ac_efl_main.offset = info->ac_efl_main;
171 p_ac_init.offset = info->ac_init;
172 p_elm_run.offset = info->elm_run;
173 p_do_app.offset = info->do_app;
182 /* ============================================================================
184 * ============================================================================
187 struct list_head list;
189 const char *app_path;
190 struct dentry *app_dentry;
191 struct probe_new p_main;
193 struct pf_group *pfg;
196 static LIST_HEAD(nsp_data_list);
198 static struct nsp_data *nsp_data_create(const char *app_path,
199 unsigned long main_addr)
201 struct dentry *dentry;
202 struct nsp_data *data;
204 dentry = dentry_by_path(app_path);
206 return ERR_PTR(-ENOENT);
208 data = kmalloc(sizeof(*data), GFP_KERNEL);
210 return ERR_PTR(-ENOMEM);
212 data->app_path = kstrdup(app_path, GFP_KERNEL);
213 if (data->app_path == NULL) {
215 return ERR_PTR(-ENOMEM);
218 data->app_dentry = dentry;
219 data->p_main.info = &pin_main;
220 data->p_main.offset = main_addr;
226 static void nsp_data_destroy(struct nsp_data *data)
228 kfree(data->app_path);
232 static struct nsp_data *nsp_data_find(const struct dentry *dentry)
234 struct nsp_data *data;
236 list_for_each_entry(data, &nsp_data_list, list) {
237 if (data->app_dentry == dentry)
244 static struct nsp_data *nsp_data_find_by_path(const char *path)
246 struct nsp_data *data;
248 list_for_each_entry(data, &nsp_data_list, list) {
249 if (strcmp(data->app_path, path) == 0)
256 static void nsp_data_add(struct nsp_data *data)
258 list_add(&data->list, &nsp_data_list);
261 static void nsp_data_rm(struct nsp_data *data)
263 list_del(&data->list);
266 static int nsp_data_inst(struct nsp_data *data)
269 struct pf_group *pfg;
271 pfg = get_pf_group_by_dentry(lpad_dentry, (void *)data->app_dentry);
275 ret = pin_register(&p_dlsym, pfg, lpad_dentry);
279 ret = pin_register(&p_dlopen, pfg, lpad_dentry);
283 ret = pin_register(&data->p_main, pfg, data->app_dentry);
287 ret = pin_register(&p_ac_efl_main, pfg, libappcore_dentry);
291 ret = pin_register(&p_ac_init, pfg, libappcore_dentry);
295 ret = pin_register(&p_elm_run, pfg, libappcore_dentry);
299 ret = pin_register(&p_do_app, pfg, libappcore_dentry);
308 pin_unregister(&p_elm_run, pfg, libappcore_dentry);
310 pin_unregister(&p_ac_init, pfg, libappcore_dentry);
312 pin_unregister(&p_ac_efl_main, pfg, libappcore_dentry);
314 pin_unregister(&data->p_main, pfg, data->app_dentry);
316 pin_unregister(&p_dlopen, pfg, lpad_dentry);
318 pin_unregister(&p_dlsym, pfg, lpad_dentry);
324 static void nsp_data_uninst(struct nsp_data *data)
326 struct pf_group *pfg = data->pfg;
328 pin_unregister(&p_do_app, pfg, libappcore_dentry);
329 pin_unregister(&p_elm_run, pfg, libappcore_dentry);
330 pin_unregister(&p_ac_init, pfg, libappcore_dentry);
331 pin_unregister(&p_ac_efl_main, pfg, libappcore_dentry);
332 pin_unregister(&data->p_main, pfg, data->app_dentry);
333 pin_unregister(&p_dlopen, pfg, lpad_dentry);
334 pin_unregister(&p_dlsym, pfg, lpad_dentry);
340 static int __nsp_add(const char *app_path, unsigned long main_addr)
342 struct nsp_data *data;
344 if (nsp_data_find_by_path(app_path))
347 data = nsp_data_create(app_path, main_addr);
349 return PTR_ERR(data);
356 static int __nsp_rm(const char *path)
358 struct dentry *dentry;
359 struct nsp_data *data;
361 dentry = dentry_by_path(path);
365 data = nsp_data_find(dentry);
370 nsp_data_destroy(data);
375 static int __nsp_rm_all(void)
377 struct nsp_data *data, *n;
379 list_for_each_entry_safe(data, n, &nsp_data_list, list) {
381 nsp_data_destroy(data);
387 static void __nsp_disabel(void)
389 struct nsp_data *data;
391 list_for_each_entry(data, &nsp_data_list, list) {
393 nsp_data_uninst(data);
397 static int __nsp_enable(void)
400 struct nsp_data *data;
402 list_for_each_entry(data, &nsp_data_list, list) {
403 ret = nsp_data_inst(data);
421 /* ============================================================================
423 * ============================================================================
425 #define F_ARG1(m, t, a) m(t, a)
426 #define F_ARG2(m, t, a, ...) m(t, a), F_ARG1(m, __VA_ARGS__)
427 #define F_ARG3(m, t, a, ...) m(t, a), F_ARG2(m, __VA_ARGS__)
428 #define F_ARG(n, m, ...) F_ARG##n(m, __VA_ARGS__)
430 #define M_TYPE_AND_ARG(t, a) t a
431 #define M_ARG(t, a) a
433 #define DECLARE_SAFE_FUNC(n, func_name, do_func, ...) \
434 int func_name(F_ARG(n, M_TYPE_AND_ARG, __VA_ARGS__)) \
437 mutex_lock(&stat_mutex); \
438 if (stat == NS_ON) { \
442 ret = do_func(F_ARG(n, M_ARG, __VA_ARGS__)); \
444 mutex_unlock(&stat_mutex); \
448 #define DECLARE_SAFE_FUNC0(name, _do) DECLARE_SAFE_FUNC(1, name, _do, void, /* */);
449 #define DECLARE_SAFE_FUNC1(name, _do, ...) DECLARE_SAFE_FUNC(1, name, _do, __VA_ARGS__);
450 #define DECLARE_SAFE_FUNC2(name, _do, ...) DECLARE_SAFE_FUNC(2, name, _do, __VA_ARGS__);
451 #define DECLARE_SAFE_FUNC3(name, _do, ...) DECLARE_SAFE_FUNC(3, name, _do, __VA_ARGS__);
454 static DEFINE_MUTEX(stat_mutex);
455 static enum nsp_stat stat = NS_OFF;
457 DECLARE_SAFE_FUNC2(nsp_add, __nsp_add, const char *, app_path,
458 unsigned long, main_addr);
459 DECLARE_SAFE_FUNC1(nsp_rm, __nsp_rm, const char *, app_path);
460 DECLARE_SAFE_FUNC0(nsp_rm_all, __nsp_rm_all);
461 DECLARE_SAFE_FUNC3(nsp_set_lpad_info, do_set_lpad_info,
462 const char *, path, unsigned long, dlopen,
463 unsigned long, dlsym);
464 DECLARE_SAFE_FUNC1(nsp_set_appcore_info, do_set_appcore_info,
465 struct appcore_info_data *, info);
471 /* ============================================================================
473 * ============================================================================
475 static int set_stat_off(void)
488 static int set_stat_on(void)
492 if (is_init() == false)
498 ret = tdata_enable();
509 int nsp_set_stat(enum nsp_stat st)
513 mutex_lock(&stat_mutex);
516 ret = set_stat_off();
522 mutex_unlock(&stat_mutex);
527 enum nsp_stat nsp_get_stat(void)
536 /* ============================================================================
538 * ============================================================================
540 static int dlopen_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
542 const char __user *user_s = (const char __user *)swap_get_uarg(regs, 0);
544 struct nsp_data *nsp_data;
546 path = strdup_from_user(user_s, GFP_ATOMIC);
550 nsp_data = nsp_data_find_by_path(path);
552 struct task_struct *task = current;
555 tdata = tdata_get(task);
557 nsp_print("ERROR: dlopen already cal for '%s'\n", path);
562 tdata = tdata_create(task);
564 tdata->stat = NPS_OPEN_E;
565 tdata->time = swap_msg_current_time();
566 tdata->nsp_data = nsp_data;
569 nsp_print("ERROR: out of memory\n");
578 static int dlopen_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
582 tdata = tdata_get(current);
586 handle = (void *)regs_return_value(regs);
587 if ((tdata->stat == NPS_OPEN_E) && handle) {
588 tdata->stat = NPS_OPEN_R;
589 tdata->handle = handle;
592 tdata_destroy(tdata);
599 static int dlsym_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
603 tdata = tdata_get(current);
605 const char __user *str = (char __user *)swap_get_uarg(regs, 1);
609 handle = (void *)swap_get_uarg(regs, 0);
610 if (handle == tdata->handle && tdata->stat == NPS_OPEN_R) {
611 name = strdup_from_user(str, GFP_ATOMIC);
612 if (name && (strcmp(name, "main") == 0))
613 tdata->stat = NPS_SYM_E;
624 static int dlsym_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
628 tdata = tdata_get(current);
630 if (tdata->stat == NPS_SYM_E)
631 tdata->stat = NPS_SYM_R;
638 static void stage_begin(enum nsp_proc_stat priv, enum nsp_proc_stat cur)
642 tdata = tdata_get(current);
644 if (tdata->stat == priv) {
646 tdata->time = swap_msg_current_time();
653 static void stage_end(enum nsp_proc_stat priv, enum nsp_proc_stat cur,
654 enum nsp_msg_stage st)
660 tdata = tdata_get(current);
662 if (tdata->stat != priv) {
668 time_start = tdata->time;
671 time_end = swap_msg_current_time();
672 nsp_msg(st, time_start, time_end);
676 static int main_h(struct kprobe *p, struct pt_regs *regs)
682 tdata = tdata_get(current);
684 if (tdata->stat != NPS_SYM_R) {
689 tdata->stat = NPS_MAIN_E;
690 time_start = tdata->time;
691 time_end = swap_msg_current_time();
692 tdata->time = time_end;
696 nsp_msg(NMS_MAPPING, time_start, time_end);
702 /* FIXME: workaround for simultaneously nsp and main() function profiling */
703 #include <retprobe/rp_msg.h>
704 #include <us_manager/us_manager.h>
706 static int main_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
708 struct uretprobe *rp = ri->rp;
711 main_h(&rp->up.kp, regs);
713 if (get_quiet() == QT_OFF) {
715 unsigned long func_addr;
717 ip = container_of(rp, struct us_ip, retprobe);
718 func_addr = (unsigned long)ip->orig_addr;
719 rp_msg_entry(regs, func_addr, "p");
726 static int main_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
728 struct uretprobe *rp = ri->rp;
730 if (rp && get_quiet() == QT_OFF) {
733 unsigned long func_addr;
734 unsigned long ret_addr;
736 ip = container_of(rp, struct us_ip, retprobe);
737 func_addr = (unsigned long)ip->orig_addr;
738 ret_addr = (unsigned long)ri->ret_addr;
739 ret_type = ip->info->rp_i.ret_type;
740 rp_msg_exit(regs, func_addr, 'n', ret_addr);
746 static int ac_efl_main_h(struct kprobe *p, struct pt_regs *regs)
748 stage_end(NPS_MAIN_E, NPS_AC_EFL_MAIN_E, NMS_MAIN);
752 static int ac_init_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
754 stage_begin(NPS_AC_EFL_MAIN_E, NPS_AC_INIT_R);
758 static int elm_run_h(struct kprobe *p, struct pt_regs *regs)
760 stage_end(NPS_AC_INIT_R, NPS_ELM_RUN_E, NMS_CREATE);
764 static int do_app_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
766 int event = swap_get_uarg(regs, 0);
767 enum { AE_RESET = 5 }; /* FIXME: hardcode */
769 if (event == AE_RESET)
770 stage_begin(NPS_ELM_RUN_E, NPS_DO_APP_E);
775 static int do_app_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
777 stage_end(NPS_DO_APP_E, NPS_DO_APP_R, NMS_RESET);