Separates probes from us_manager.
Now all new probe types should register their methods
using special interface declared in us_manager/probes/register_probes.h
To use probes methods, include us_manager/probes/use_probes.h.
Change-Id: I07c7452789b8eec42cd5372ad2b69a5b8d56804b
Signed-off-by: Alexander Aksenov <a.aksenov@samsung.com>
ks_features/ \
sampler/ \
energy/ \
- parser/
+ parser/ \
+ retprobe/
sampler_dir=${modules_dir}/sampler
energy_dir=${modules_dir}/energy
parser_dir=${modules_dir}/parser
+retprobe_dir=${modules_dir}/retprobe
buffer_module_name=swap_buffer.ko
driver_module_name=swap_driver.ko
energy_module_name=swap_energy.ko
parser_module_name=swap_message_parser.ko
ksyms_module_name=swap_ksyms.ko
+retprobe_module_name=swap_retprobe.ko
install_dir="/opt/swap/sdk"
${sampler_dir}/${sampler_module_name} \
${energy_dir}/${energy_module_name} \
${parser_dir}/${parser_module_name} \
-${ksyms_dir}/${ksyms_module_name}"
+${ksyms_dir}/${ksyms_module_name} \
+${retprobe_dir}/${retprobe_module_name}"
for m in ${modules} ; do
${cross_compile}strip -x -g $m
#include <linux/errno.h>
#include <linux/namei.h>
#include <us_manager/pf/pf_group.h>
+#include <us_manager/probes/probes.h>
+
#include "msg_parser.h"
#include "us_inst.h"
switch (mt) {
case MT_ADD:
- ret = pf_register_probe(pfg, dentry, func->addr, func->args,
- func->ret_type);
+ {
+ struct probe_info probe_i;
+
+ /* ARM toolchain hates good style initialization of struct with union */
+ probe_i.probe_type = SWAP_RETPROBE;
+ probe_i.rp_i.args = func->args;
+ probe_i.rp_i.ret_type = func->ret_type;
+ probe_i.rp_i.size = 0;
+ ret = pf_register_probe(pfg, dentry, func->addr, &probe_i);
break;
+ }
case MT_DEL:
ret = pf_unregister_probe(pfg, dentry, func->addr);
break;
--- /dev/null
+EXTRA_CFLAGS := $(extra_cflags)
+
+obj-m := swap_retprobe.o
+swap_retprobe-y := retprobe.o
--- /dev/null
+/*
+ * SWAP uprobe manager
+ * modules/retprobe/retprobe.c
+ *
+ * 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, 2014
+ *
+ * 2014 Alexander Aksenov: Probes interface implement
+ *
+ */
+
+#include "retprobe.h"
+#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>
+
+static int retprobe_copy(struct probe_info *dest,
+ const struct probe_info *source)
+{
+ size_t len;
+
+ memcpy(dest, source, sizeof(*source));
+
+ len = strlen(source->rp_i.args) + 1;
+ dest->rp_i.args = kmalloc(len, GFP_KERNEL);
+ if (dest->rp_i.args == NULL)
+ return -ENOMEM;
+ memcpy(dest->rp_i.args, source->rp_i.args, len);
+
+ return 0;
+}
+
+
+static void retprobe_cleanup(struct probe_info *probe_i)
+{
+ kfree(probe_i->rp_i.args);
+}
+
+
+
+static struct uprobe *retprobe_get_uprobe(struct us_ip *ip)
+{
+ return &ip->retprobe.up;
+}
+
+static int retprobe_register_probe(struct us_ip *ip)
+{
+ return swap_register_uretprobe(&ip->retprobe);
+}
+
+static void retprobe_unregister_probe(struct us_ip *ip, int disarm)
+{
+ __swap_unregister_uretprobe(&ip->retprobe, disarm);
+}
+
+
+static int retprobe_entry_handler(struct uretprobe_instance *ri, struct pt_regs *regs)
+{
+ struct uretprobe *rp = ri->rp;
+
+ 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;
+
+ entry_event(fmt, addr, regs, PT_US, PST_NONE);
+ }
+
+ return 0;
+}
+
+static int retprobe_ret_handler(struct uretprobe_instance *ri, struct pt_regs *regs)
+{
+ struct uretprobe *rp = ri->rp;
+
+ 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;
+
+ exit_event(ip->probe_i.rp_i.ret_type, regs, PT_US, PST_NONE, addr,
+ ret_addr);
+ }
+
+ return 0;
+}
+
+static void retprobe_init(struct us_ip *ip)
+{
+ ip->retprobe.entry_handler = retprobe_entry_handler;
+ ip->retprobe.handler = retprobe_ret_handler;
+ ip->retprobe.maxactive = 0;
+}
+
+static void retprobe_uninit(struct us_ip *ip)
+{
+ retprobe_cleanup(&ip->probe_i);
+}
+
+
+static struct probe_iface retprobe_iface = {
+ .init = retprobe_init,
+ .uninit = retprobe_uninit,
+ .reg = retprobe_register_probe,
+ .unreg = retprobe_unregister_probe,
+ .get_uprobe = retprobe_get_uprobe,
+ .copy = retprobe_copy,
+ .cleanup = retprobe_cleanup
+};
+
+static int __init retprobe_module_init(void)
+{
+ return swap_register_probe_type(SWAP_RETPROBE, &retprobe_iface);
+}
+
+static void __exit retprobe_module_exit(void)
+{
+ swap_unregister_probe_type(SWAP_RETPROBE);
+}
+
+module_init(retprobe_module_init);
+module_exit(retprobe_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SWAP retprobe");
+MODULE_AUTHOR("Alexander Aksenov <a.aksenov@samsung.com>");
--- /dev/null
+/*
+ * SWAP uprobe manager
+ * modules/us_manager/probes/uretprobe.h
+ *
+ * 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, 2014
+ *
+ * 2014 Alexander Aksenov: Probes interface implement
+ *
+ */
+
+#ifndef __URETPROBE_H__
+#define __URETPROBE_H__
+
+/* Common retprobe info */
+struct retprobe_info {
+ char *args;
+ char ret_type;
+};
+
+#endif /* __URETPROBE_H__ */
sspt/ip.o sspt/sspt_page.o sspt/sspt_file.o sspt/sspt_proc.o \
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
+ img/img_proc.o img/img_file.o img/img_ip.o \
+ probes/probes.o
*
* @param file Pointer to the img_file struct
* @param addr Function address
- * @param args Function arguments
- * @param ret_type Return type
+ * @param probe_Pointer to a probe_info structure with an information about
+ * the probe.
* @return Error code
*/
int img_file_add_ip(struct img_file *file, unsigned long addr,
- const char *args, char ret_type)
+ struct probe_info *probe_i)
{
struct img_ip *ip;
return 0;
}
- ip = create_img_ip(addr, args, ret_type);
+ ip = create_img_ip(addr, probe_i);
img_add_ip_by_list(file, ip);
return 0;
#include <linux/types.h>
+struct probe_info;
+
/**
* @struct img_file
* @breaf Image of file
void free_img_file(struct img_file *ip);
int img_file_add_ip(struct img_file *file, unsigned long addr,
- const char *args, char ret_type);
+ struct probe_info *probe_i);
int img_file_del_ip(struct img_file *file, unsigned long addr);
int img_file_empty(struct img_file *file);
#include "img_ip.h"
+#include <us_manager/probes/use_probes.h>
#include <linux/slab.h>
/**
* @brief Create img_ip struct
*
* @param addr Function address
- * @param args Function arguments
- * @param ret_type Return type
+ * @param probe_i Pointer to the probe info data.
* @return Pointer to the created img_ip struct
*/
-struct img_ip *create_img_ip(unsigned long addr, const char *args,
- char ret_type)
+struct img_ip *create_img_ip(unsigned long addr, struct probe_info *probe_i)
{
struct img_ip *ip;
- size_t len;
ip = kmalloc(sizeof(*ip), GFP_KERNEL);
INIT_LIST_HEAD(&ip->list);
ip->addr = addr;
- /* copy args */
- len = strlen(args) + 1;
- ip->args = kmalloc(len, GFP_KERNEL);
- memcpy(ip->args, args, len);
-
- ip->ret_type = ret_type;
+ probe_info_copy(probe_i, &ip->probe_i);
return ip;
}
*/
void free_img_ip(struct img_ip *ip)
{
- kfree(ip->args);
+ probe_info_cleanup(&ip->probe_i);
kfree(ip);
}
/* debug */
void img_ip_print(struct img_ip *ip)
{
- printk("### addr=8%lx, args=%s\n", ip->addr, ip->args);
+ if (ip->probe_i.probe_type == SWAP_RETPROBE)
+ printk("### addr=8%lx, args=%s\n", ip->addr,
+ ip->probe_i.rp_i.args);
}
/* debug */
#define _IMG_IP_H
#include <linux/types.h>
+#include <us_manager/probes/probes.h>
/**
* @struct img_ip
struct img_ip {
struct list_head list; /**< For img_file */
unsigned long addr; /**< Function address */
- char *args; /**< Function arguments */
- char ret_type; /**< Return type */
+ struct probe_info probe_i; /**< Probe info */
};
-struct img_ip *create_img_ip(unsigned long addr, const char *args,
- char ret_type);
+struct img_ip *create_img_ip(unsigned long addr, struct probe_info *probe_i);
void free_img_ip(struct img_ip *ip);
/* debug */
* @param proc Pointer to the img_proc struct
* @param dentry Dentry of file
* @param addr Function address
- * @param args Function address
- * @param ret_type Return type
+ * @param probe_i Pointer to a probe_info struct related with the probe
* @return Error code
*/
int img_proc_add_ip(struct img_proc *proc, struct dentry *dentry,
- unsigned long addr, const char *args, char ret_type)
+ unsigned long addr, struct probe_info *probe_i)
{
int ret;
struct img_file *file;
file = find_img_file(proc, dentry);
if (file)
- return img_file_add_ip(file, addr, args, ret_type);
+ return img_file_add_ip(file, addr, probe_i);
file = create_img_file(dentry);
- ret = img_file_add_ip(file, addr, args, ret_type);
+ ret = img_file_add_ip(file, addr, probe_i);
if (ret) {
printk("Cannot add ip to img file\n");
free_img_file(file);
#include <linux/types.h>
struct dentry;
+struct probe_info;
/**
* @struct img_proc
void free_img_proc(struct img_proc *proc);
int img_proc_add_ip(struct img_proc *proc, struct dentry *dentry,
- unsigned long addr, const char *args, char ret_type);
+ unsigned long addr, struct probe_info *probe_i);
int img_proc_del_ip(struct img_proc *proc, struct dentry *dentry, unsigned long addr);
/* debug */
file = sspt_proc_find_file_or_new(proc, i_file->dentry);
list_for_each_entry(i_ip, &i_file->ip_list, list)
- sspt_file_add_ip(file, i_ip->addr, i_ip->args,
- i_ip->ret_type);
+ sspt_file_add_ip(file, i_ip->addr, &i_ip->probe_i);
}
}
* @param pfg Pointer to the pf_group struct
* @param dentry Dentry of file
* @param offset Function offset
- * @param args Function arguments
- * @param ret_type Return type
+ * @param probe_info Pointer to the related probe_info struct
* @return Error code
*/
int pf_register_probe(struct pf_group *pfg, struct dentry *dentry,
- unsigned long offset, const char *args, char ret_type)
+ unsigned long offset, struct probe_info *probe_i)
{
- return img_proc_add_ip(pfg->i_proc, dentry, offset, args, ret_type);
+ return img_proc_add_ip(pfg->i_proc, dentry, offset, probe_i);
}
EXPORT_SYMBOL_GPL(pf_register_probe);
struct dentry;
struct pf_group;
struct sspt_proc;
+struct probe_info;
struct pf_group *get_pf_group_by_dentry(struct dentry *dentry, void *priv);
struct pf_group *get_pf_group_by_tgid(pid_t tgid, void *priv);
void put_pf_group(struct pf_group *pfg);
int pf_register_probe(struct pf_group *pfg, struct dentry *dentry,
- unsigned long offset, const char *args, char ret_type);
+ unsigned long offset, struct probe_info *probe_i);
int pf_unregister_probe(struct pf_group *pfg, struct dentry *dentry,
unsigned long offset);
--- /dev/null
+/*
+ * SWAP uprobe manager
+ * modules/us_manager/probes/probes.c
+ *
+ * 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, 2014
+ *
+ * 2014 Alexander Aksenov: Probes interface implement
+ *
+ */
+
+#include "probes.h"
+#include "register_probes.h"
+#include "use_probes.h"
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+
+static struct probe_iface *probes_methods[SWAP_PROBE_MAX_VAL] = { NULL };
+
+/* 1 - correct probe type
+ 0 - wrong probe type
+*/
+static inline int correct_probe_type(enum probe_t probe_type)
+{
+ if (probe_type >= SWAP_PROBE_MAX_VAL)
+ return 0;
+
+ return 1;
+}
+
+static inline int methods_exist(enum probe_t probe_type)
+{
+ if (!correct_probe_type(probe_type))
+ return 0;
+
+ if (probes_methods[probe_type] == NULL)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * @brief Calls specified probe type init method.
+ *
+ * @param pi Pointer to the probe_info.
+ * @param ip Pointer to the probe us_ip struct.
+ * @return Void.
+ */
+void probe_info_init(struct probe_info *pi, struct us_ip *ip)
+{
+ enum probe_t probe_type = pi->probe_type;
+
+ if (!methods_exist(probe_type)) {
+ printk(KERN_WARNING "SWAP US_MANAGER: Wrong probe type!\n");
+ return;
+ }
+
+ probes_methods[probe_type]->init(ip);
+}
+
+/**
+ * @brief Calls specified probe type uninit method.
+ *
+ * @param pi Pointer to the probe_info.
+ * @param ip Pointer to the probe us_ip struct.
+ * @return Void.
+ */
+void probe_info_uninit(struct probe_info *pi, struct us_ip *ip)
+{
+ enum probe_t probe_type = pi->probe_type;
+
+ if (!methods_exist(probe_type)) {
+ printk(KERN_WARNING "SWAP US_MANAGER: Wrong probe type!\n");
+ return;
+ }
+
+ probes_methods[probe_type]->uninit(ip);
+}
+
+/**
+ * @brief Calls specified probe type register method.
+ *
+ * @param pi Pointer to the probe_info.
+ * @param ip Pointer to the probe us_ip struct.
+ * @return -EINVAL on wrong probe type, method result otherwise.
+ */
+int probe_info_register(struct probe_info *pi, struct us_ip *ip)
+{
+ enum probe_t probe_type = pi->probe_type;
+
+ if (!methods_exist(probe_type)) {
+ printk(KERN_WARNING "SWAP US_MANAGER: Wrong probe type!\n");
+ return -EINVAL;
+ }
+
+ return probes_methods[probe_type]->reg(ip);
+}
+
+/**
+ * @brief Calls specified probe type unregister method.
+ *
+ * @param pi Pointer to the probe_info.
+ * @param ip Pointer to the probe us_ip struct.
+ * @param disarm Disarm flag.
+ * @return Void.
+ */
+void probe_info_unregister(struct probe_info *pi, struct us_ip *ip, int disarm)
+{
+ enum probe_t probe_type = pi->probe_type;
+
+ if (!methods_exist(probe_type)) {
+ printk(KERN_WARNING "SWAP US_MANAGER: Wrong probe type!\n");
+ return;
+ }
+
+ probes_methods[probe_type]->unreg(ip, disarm);
+}
+
+/**
+ * @brief Calls specified probe type get underlying uprobe method.
+ *
+ * @param pi Pointer to the probe_info.
+ * @param ip Pointer to the probe us_ip struct.
+ * @return Pointer to the uprobe struct, NULL on error.
+ */
+struct uprobe *probe_info_get_uprobe(struct probe_info *pi, struct us_ip *ip)
+{
+ enum probe_t probe_type = pi->probe_type;
+
+ if (!methods_exist(probe_type)) {
+ printk(KERN_WARNING "SWAP US_MANAGER: Wrong probe type!\n");
+ return NULL;
+ }
+
+ return probes_methods[probe_type]->get_uprobe(ip);
+}
+
+/**
+ * @brief Calls specified probe type copy method.
+ *
+ * @param pi Pointer to the source probe_info.
+ * @param dest Pointer to the probe us_ip struct.
+ * @return -EINVAL on error, method result otherwise.
+ */
+int probe_info_copy(const struct probe_info *pi, struct probe_info *dest)
+{
+ enum probe_t probe_type = pi->probe_type;
+
+ if (!methods_exist(probe_type)) {
+ printk(KERN_WARNING "SWAP US_MANAGER: Wrong probe type!\n");
+ return -EINVAL;
+ }
+
+ return probes_methods[probe_type]->copy(dest, pi);
+}
+
+/**
+ * @brief Calls specified probe type cleanup method.
+ *
+ * @param pi Pointer to the source probe_info.
+ * @return Void.
+ */
+void probe_info_cleanup(struct probe_info *pi)
+{
+ enum probe_t probe_type = pi->probe_type;
+
+ if (!methods_exist(probe_type)) {
+ printk(KERN_WARNING "SWAP US_MANAGER: Wrong probe type!\n");
+ return;
+ }
+
+ probes_methods[probe_type]->cleanup(pi);
+}
+
+/**
+ * @brief Registers probe type.
+ *
+ * @param probe_type Number, associated with this probe type.
+ * @param pi Pointer to the probe interface structure
+ * @return 0 on succes, error code on error.
+ */
+int swap_register_probe_type(enum probe_t probe_type, struct probe_iface *pi)
+{
+ if (!correct_probe_type(probe_type)) {
+ printk(KERN_ERR "SWAP US_MANAGER: Wrong probe type!\n");
+ return -EINVAL;
+ }
+
+ if (probes_methods[probe_type] != NULL)
+ printk(KERN_WARNING "SWAP US_MANAGER: Re-registering probe %d\n",
+ probe_type);
+
+ probes_methods[probe_type] = pi;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(swap_register_probe_type);
+
+/**
+ * @brief Unregisters probe type.
+ *
+ * @param probe_type Probe type that should be unregistered.
+ * @return Void.
+ */
+void swap_unregister_probe_type(enum probe_t probe_type)
+{
+ if (!correct_probe_type(probe_type)) {
+ printk(KERN_ERR "SWAP US_MANAGER: Wrong probe type!\n");
+ return;
+ }
+
+ probes_methods[probe_type] = NULL;
+}
+EXPORT_SYMBOL_GPL(swap_unregister_probe_type);
--- /dev/null
+/*
+ * SWAP uprobe manager
+ * modules/us_manager/probes/probes.h
+ *
+ * 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, 2014
+ *
+ * 2014 Alexander Aksenov: Probes interface implement
+ *
+ */
+
+
+#ifndef __PROBES_H__
+#define __PROBES_H__
+
+#include <linux/types.h>
+
+#include <retprobe/retprobe.h> /* TODO Remove */
+
+
+
+/* All probe types. Only us_manager should know about them - it is its own
+ * business to install proper probes on proper places.
+ */
+enum probe_t {
+ SWAP_RETPROBE = 0, /* Retprobe */
+ SWAP_PROBE_MAX_VAL /* Probes max value. */
+};
+
+/* Probe info stuct. It contains the whole information about probe. */
+struct probe_info {
+ enum probe_t probe_type;
+ size_t size;
+ /* Union of all SWAP supported probe types */
+ union {
+ struct retprobe_info rp_i;
+ };
+};
+
+#endif /* __PROBES_H__ */
--- /dev/null
+#ifndef __REGISTER_PROBES_H__
+#define __REGISTER_PROBES_H__
+
+#include "probes.h"
+
+struct us_ip;
+
+struct probe_iface {
+ void (*init)(struct us_ip *);
+ void (*uninit)(struct us_ip *);
+ int (*reg)(struct us_ip *);
+ void (*unreg)(struct us_ip *, int);
+ struct uprobe *(*get_uprobe)(struct us_ip *);
+ int (*copy)(struct probe_info *, const struct probe_info *);
+ void (*cleanup)(struct probe_info *);
+};
+
+int swap_register_probe_type(enum probe_t probe_type, struct probe_iface *pi);
+void swap_unregister_probe_type(enum probe_t probe_type);
+
+#endif /* __REGISTER_PROBES_H__ */
--- /dev/null
+#ifndef __USE_PROBES_H__
+#define __USE_PROBES_H__
+
+#include "probes.h"
+
+struct us_ip;
+
+void probe_info_init(struct probe_info *pi, struct us_ip *ip);
+void probe_info_uninit(struct probe_info *pi, struct us_ip *ip);
+int probe_info_register(struct probe_info *pi, struct us_ip *ip);
+void probe_info_unregister(struct probe_info *pi, struct us_ip *ip, int disarm);
+struct uprobe *probe_info_get_uprobe(struct probe_info *pi, struct us_ip *ip);
+int probe_info_copy(const struct probe_info *pi, struct probe_info *dest);
+void probe_info_cleanup(struct probe_info *pi);
+
+#endif /* __USE_PROBES_H__ */
#include "ip.h"
#include "sspt_page.h"
#include "sspt_file.h"
-#include <writer/swap_writer_module.h>
-#include <us_manager/us_manager.h>
-
-
-static int entry_handler(struct uretprobe_instance *ri, struct pt_regs *regs)
-{
- struct uretprobe *rp = ri->rp;
-
- if (rp && get_quiet() == QT_OFF) {
- struct us_ip *ip = container_of(rp, struct us_ip, retprobe);
- const char *fmt = ip->args;
- unsigned long addr = (unsigned long)ip->orig_addr;
-
- entry_event(fmt, addr, regs, PT_US, PST_NONE);
- }
-
- return 0;
-}
-
-static int ret_handler(struct uretprobe_instance *ri, struct pt_regs *regs)
-{
- struct uretprobe *rp = ri->rp;
-
- 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;
-
- exit_event(ip->ret_type, regs, PT_US, PST_NONE, addr, ret_addr);
- }
-
- return 0;
-}
+#include <us_manager/probes/use_probes.h>
/**
* @brief Create us_ip struct
*
* @param offset Function offset from the beginning of the page
- * @param args Function arguments
- * @param ret_type Return type
+ * @param probe_i Pointer to the probe data.
* @return Pointer to the created us_ip struct
*/
-struct us_ip *create_ip(unsigned long offset, const char *args, char ret_type)
+struct us_ip *create_ip(unsigned long offset, const struct probe_info *probe_i)
{
- size_t len = strlen(args) + 1;
- struct us_ip *ip = kmalloc(sizeof(*ip) + len, GFP_ATOMIC);
+ size_t len = probe_i->size;
+ struct us_ip *ip;
+ ip = kmalloc(sizeof(*ip) + len, GFP_ATOMIC);
if (ip != NULL) {
- memset(ip, 0, sizeof(*ip));
+ memset(ip, 0, sizeof(*ip) + len);
INIT_LIST_HEAD(&ip->list);
ip->offset = offset;
- ip->args = (char *)ip + sizeof(*ip);
- ip->ret_type = ret_type;
-
- /* copy args */
- memcpy(ip->args, args, len);
- /* retprobe */
- ip->retprobe.handler = ret_handler;
- ip->retprobe.entry_handler = entry_handler;
+ probe_info_copy(probe_i, &ip->probe_i);
+ probe_info_init(&ip->probe_i, ip);
} else {
printk("Cannot kmalloc in create_ip function!\n");
}
*/
void free_ip(struct us_ip *ip)
{
+ probe_info_uninit(&ip->probe_i, ip);
kfree(ip);
}
#include <linux/list.h>
#include <uprobe/swap_uprobes.h>
+#include <us_manager/probes/probes.h>
struct sspt_page;
* @breaf Image of instrumentation pointer for specified process
*/
struct us_ip {
- struct list_head list; /**< For sspt_page */
- struct sspt_page *page; /**< Pointer on the page (parent) */
+ struct list_head list; /**< For sspt_page */
+ struct sspt_page *page; /**< Pointer on the page (parent) */
+ struct probe_info probe_i; /**< Probe's data */
- struct uretprobe retprobe; /**< uretprobe */
- char *args; /**< Function arguments */
- char ret_type; /**< Return type */
- unsigned long orig_addr; /**< Function address */
+ unsigned long orig_addr; /**< Function address */
+ unsigned long offset; /**< Page offset */
- unsigned long offset; /**< Page offset */
+ union {
+ struct uretprobe retprobe;
+ struct uprobe uprobe;
+ };
};
-struct us_ip *create_ip(unsigned long offset, const char *args, char ret_type);
+struct us_ip *create_ip(unsigned long offset, const struct probe_info *probe_i);
void free_ip(struct us_ip *ip);
#endif /* __IP__ */
#include <us_manager/us_manager.h>
#include <us_manager/pf/pf_group.h>
+#include <us_manager/probes/use_probes.h>
static inline int check_vma(struct vm_area_struct *vma)
static inline int sspt_register_usprobe(struct us_ip *ip)
{
int ret;
+ struct uprobe *up = NULL;
- /* for retuprobe */
- ip->retprobe.up.task = ip->page->file->proc->task;
- ip->retprobe.up.sm = ip->page->file->proc->sm;
+ up = probe_info_get_uprobe(&ip->probe_i, ip);
- ret = swap_register_uretprobe(&ip->retprobe);
+ if (!up) {
+ printk("SWAP US_MANAGER: failed getting uprobe!\n");
+ return -EINVAL;
+ }
+
+ up->task = ip->page->file->proc->task;
+ up->sm = ip->page->file->proc->sm;
+
+ ret = probe_info_register(&ip->probe_i, ip);
if (ret) {
struct sspt_file *file = ip->page->file;
char *name = file->dentry->d_iname;
- unsigned long addr = (unsigned long)ip->retprobe.up.kp.addr;
+ unsigned long addr = (unsigned long)up->kp.addr;
unsigned long offset = addr - file->vm_start;
printk("swap_register_uretprobe() failure %d (%s:%lx|%lx)\n",
return ret;
}
-static inline int do_unregister_usprobe(struct us_ip *ip, int disarm)
-{
- __swap_unregister_uretprobe(&ip->retprobe, disarm);
-
- return 0;
-}
-
static inline int sspt_unregister_usprobe(struct task_struct *task, struct us_ip *ip, enum US_FLAGS flag)
{
- int err = 0;
+ struct uprobe *up = NULL;
switch (flag) {
case US_UNREGS_PROBE:
- err = do_unregister_usprobe(ip, 1);
+ probe_info_unregister(&ip->probe_i, ip, 1);
break;
case US_DISARM:
- disarm_uprobe(&ip->retprobe.up.kp, task);
+ up = probe_info_get_uprobe(&ip->probe_i, ip);
+ disarm_uprobe(&up->kp, task);
break;
case US_UNINSTALL:
- err = do_unregister_usprobe(ip, 0);
+ probe_info_unregister(&ip->probe_i, ip, 0);
break;
default:
panic("incorrect value flag=%d", flag);
}
- return err;
+ return 0;
}
#endif /* __SSPT__ */
*/
#include <kprobe/swap_kprobes_deps.h>
+#include <us_manager/probes/probes.h>
static inline void print_jprobe(struct jprobe *jp)
{
static inline void print_ip(struct us_ip *ip, int i)
{
- printk("### addr[%2d]=%lx, R_addr=%lx\n",
- i, (unsigned long)ip->offset,
- (unsigned long)ip->retprobe.up.kp.addr);
- print_retprobe(&ip->retprobe);
+ if (ip->probe_i.probe_type == SWAP_RETPROBE) {
+ struct uretprobe *rp = &ip->retprobe;
+
+ printk("### addr[%2d]=%lx, R_addr=%lx\n",
+ i, (unsigned long)ip->offset,
+ (unsigned long)rp->up.kp.addr);
+ print_retprobe(rp);
+ }
}
static inline void print_page_probes(const struct sspt_page *page)
* @return Void
*/
void sspt_file_add_ip(struct sspt_file *file, unsigned long offset,
- const char *args, char ret_type)
+ struct probe_info *probe_i)
{
struct sspt_page *page = sspt_find_page_or_new(file, offset & PAGE_MASK);
// FIXME: delete ip
- struct us_ip *ip = create_ip(offset, args, ret_type);
+ struct us_ip *ip = create_ip(offset, probe_i);
sspt_add_ip(page, ip);
}
struct sspt_page *sspt_find_page_mapped(struct sspt_file *file,
unsigned long page);
void sspt_file_add_ip(struct sspt_file *file, unsigned long offset,
- const char *args, char ret_type);
+ struct probe_info *probe_i);
struct sspt_page *sspt_get_page(struct sspt_file *file, unsigned long offset_addr);
void sspt_put_page(struct sspt_page *page);
#include "sspt_page.h"
#include "sspt_file.h"
#include "ip.h"
+#include <us_manager/probes/use_probes.h>
#include <linux/slab.h>
#include <linux/list.h>
int err = 0;
struct us_ip *ip, *n;
struct list_head ip_list_tmp;
+ struct uprobe *up;
unsigned long addr;
spin_lock(&page->lock);
addr = file->vm_start + page->offset + ip->offset;
ip->orig_addr = addr;
- ip->retprobe.up.kp.addr = (kprobe_opcode_t *)addr;
+ up = probe_info_get_uprobe(&ip->probe_i, ip);
+ up->kp.addr = (kprobe_opcode_t *)addr;
err = sspt_register_usprobe(ip);
if (err) {