{
struct uprobe *up = container_of(p, struct uprobe, kp);
struct us_ip *ip = container_of(up, struct us_ip, uprobe);
- struct fbi_info *fbi_i = &ip->probe_i.fbi_i;
+ struct fbi_info *fbi_i = &ip->info->fbi_i;
struct fbi_var_data *fbi_d = NULL;
uint8_t i;
- if (ip->probe_i.probe_type != SWAP_FBIPROBE) {
+ if (ip->info->probe_type != SWAP_FBIPROBE) {
/* How this can occure? Doesn't matter, just print and go */
print_err("Not FBI probe in FBI handler!\n");
return 0;
void fbi_probe_uninit(struct us_ip *ip)
{
if (ip != NULL)
- fbi_probe_cleanup(&ip->probe_i);
+ fbi_probe_cleanup(ip->info);
}
static int fbi_probe_register_probe(struct us_ip *ip)
if (__is_instrumented(caller))
return INTERNAL_CALL;
- if (ip->probe_i.pl_i.type & SWAP_PRELOAD_ALWAYS)
+ if (ip->info->pl_i.type & SWAP_PRELOAD_ALWAYS)
return EXTERNAL_CALL;
return NOT_INSTRUMENTED;
static inline bool __is_probe_non_block(struct us_ip *ip)
{
- if (!(ip->probe_i.pl_i.type & (0x1 << 1)))
+ if (!(ip->info->pl_i.type & (0x1 << 1)))
return true;
return false;
struct us_ip *ip = container_of(ri->rp, struct us_ip, retprobe);
struct us_priv *priv = (struct us_priv *)ri->data;
unsigned long flags = get_preload_flags(current);
- unsigned long offset = ip->probe_i.pl_i.handler;
+ unsigned long offset = ip->info->pl_i.handler;
unsigned long vaddr = 0;
char __user *path = NULL;
struct us_ip *ip = container_of(ri->rp, struct us_ip, retprobe);
struct us_priv *priv = (struct us_priv *)ri->data;
unsigned long flags = get_preload_flags(current);
- unsigned long offset = ip->probe_i.pl_i.handler;
+ unsigned long offset = ip->info->pl_i.handler;
unsigned long vaddr = 0;
switch (preload_pd_get_state(pd)) {
{
preload_module_uprobe_exit(ip);
- preload_info_cleanup(&ip->probe_i);
+ preload_info_cleanup(ip->info);
}
static struct probe_iface preload_iface = {
{
preload_module_get_caller_exit(ip);
- get_caller_info_cleanup(&ip->probe_i);
+ get_caller_info_cleanup(ip->info);
}
static struct probe_iface get_caller_iface = {
{
preload_module_get_call_type_exit(ip);
- get_caller_info_cleanup(&ip->probe_i);
+ get_caller_info_cleanup(ip->info);
}
static struct probe_iface get_call_type_iface = {
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;
+ const char *fmt = ip->info->rp_i.args;
const unsigned long func_addr = (unsigned long)ip->orig_addr;
rp_msg_entry(regs, func_addr, fmt);
struct us_ip *ip = container_of(rp, struct us_ip, retprobe);
const unsigned long func_addr = (unsigned long)ip->orig_addr;
const unsigned long ret_addr = (unsigned long)ri->ret_addr;
- const char ret_type = ip->probe_i.rp_i.ret_type;
+ const char ret_type = ip->info->rp_i.ret_type;
rp_msg_exit(regs, func_addr, ret_type, ret_addr);
}
static void retprobe_uninit(struct us_ip *ip)
{
- retprobe_cleanup(&ip->probe_i);
+ retprobe_cleanup(ip->info);
}
* @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, struct probe_info *probe_i)
+struct img_ip *create_img_ip(unsigned long addr, struct probe_info *info)
{
struct img_ip *ip;
ip = kmalloc(sizeof(*ip), GFP_KERNEL);
- INIT_LIST_HEAD(&ip->list);
- ip->addr = addr;
+ if (ip) {
+ struct probe_info *info_new;
- probe_info_copy(probe_i, &ip->probe_i);
+ info_new = probe_info_dup(info);
+ if (info_new == NULL) {
+ kfree(ip);
+ return NULL;
+ }
+
+ probe_info_copy(info, info_new);
+
+ INIT_LIST_HEAD(&ip->list);
+ ip->addr = addr;
+ ip->info = info_new;
+ }
return ip;
}
*/
void free_img_ip(struct img_ip *ip)
{
- probe_info_cleanup(&ip->probe_i);
+ probe_info_cleanup(ip->info);
+ probe_info_free(ip->info);
kfree(ip);
}
/* debug */
void img_ip_print(struct img_ip *ip)
{
- if (ip->probe_i.probe_type == SWAP_RETPROBE)
+ if (ip->info->probe_type == SWAP_RETPROBE)
printk(KERN_INFO "### addr=8%lx, args=%s\n",
- ip->addr, ip->probe_i.rp_i.args);
+ ip->addr, ip->info->rp_i.args);
}
/* debug */
struct img_ip {
struct list_head list; /**< For img_file */
unsigned long addr; /**< Function address */
- struct probe_info probe_i; /**< Probe info */
+ struct probe_info *info; /**< Probe info */
};
-struct img_ip *create_img_ip(unsigned long addr, struct probe_info *probe_i);
+struct img_ip *create_img_ip(unsigned long addr, struct probe_info *info);
void free_img_ip(struct img_ip *ip);
/* 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->probe_i);
+ sspt_file_add_ip(file, i_ip->addr, i_ip->info);
}
}
#include "register_probes.h"
#include "use_probes.h"
+#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
+
+struct probe_info *probe_info_malloc(size_t size, enum probe_t type)
+{
+ struct probe_info *info;
+
+ info = kmalloc(sizeof(*info) + size, GFP_ATOMIC);
+ if (info) {
+ info->probe_type = type;
+ info->size = size;
+ }
+
+ return info;
+}
+EXPORT_SYMBOL_GPL(probe_info_malloc);
+
+struct probe_info *probe_info_dup(const struct probe_info *info)
+{
+ struct probe_info *info_new;
+ size_t size = info->size;
+
+ info_new = probe_info_malloc(size, info->probe_type);
+ if (info_new && size)
+ memcpy(info_new->data, info->data, size);
+
+ return info_new;
+}
+EXPORT_SYMBOL_GPL(probe_info_dup);
+
+void probe_info_free(struct probe_info *info)
+{
+ kfree(info);
+}
+EXPORT_SYMBOL_GPL(probe_info_free);
+
+
static struct probe_iface *probes_methods[SWAP_PROBE_MAX_VAL] = { NULL };
/* 1 - correct probe type
struct get_caller_info gc_i;
struct get_call_type_info gct_i;
};
+
+ char data[0];
};
+
+#define probe_info_create(val_t, type) probe_info_malloc(sizeof(val_t), type)
+struct probe_info *probe_info_malloc(size_t size, enum probe_t type);
+struct probe_info *probe_info_dup(const struct probe_info *info);
+void probe_info_free(struct probe_info *info);
+
+
+#define probe_info_get_data(info) ((void *)(info->data))
+#define probe_info_get_ptr(info, val_t) (val_t *)probe_info_get_data(info)
+#define probe_info_get_val(info, val_t) *probe_info_get_ptr(info, val_t)
+#define probe_info_set_val(info, val_t, v) *probe_info_get_ptr(info, val_t) = v
+
+
#endif /* __PROBES_H__ */
* @param page Pointer to the parent sspt_page struct
* @return Pointer to the created us_ip struct
*/
-struct us_ip *create_ip(unsigned long offset, const struct probe_info *probe_i,
+struct us_ip *create_ip(unsigned long offset, const struct probe_info *info,
struct sspt_page *page)
{
- size_t len = probe_i->size;
struct us_ip *ip;
+ struct probe_info *info_new;
- ip = kmalloc(sizeof(*ip) + len, GFP_ATOMIC);
+ info_new = probe_info_dup(info);
+ if (info_new == NULL) {
+ printk("Cannot probe_info_dup in %s function!\n", __func__);
+ return NULL;
+ }
+
+ ip = kmalloc(sizeof(*ip), GFP_ATOMIC);
if (ip != NULL) {
- memset(ip, 0, sizeof(*ip) + len);
+ memset(ip, 0, sizeof(*ip));
INIT_LIST_HEAD(&ip->list);
ip->offset = offset;
ip->page = page;
- probe_info_copy(probe_i, &ip->probe_i);
- probe_info_init(&ip->probe_i, ip);
+ probe_info_copy(info, info_new);
+ probe_info_init(info_new, ip);
+ ip->info = info_new;
} else {
printk(KERN_INFO "Cannot kmalloc in create_ip function!\n");
+ probe_info_free(info_new);
}
return ip;
*/
void free_ip(struct us_ip *ip)
{
- probe_info_uninit(&ip->probe_i, ip);
+ probe_info_uninit(ip->info, ip);
+ probe_info_free(ip->info);
kfree(ip);
}
struct us_ip {
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 probe_info *info; /**< Probe's data */
unsigned long orig_addr; /**< Function address */
unsigned long offset; /**< Page offset */
#define to_us_ip(rp) container_of(rp, struct us_ip, retprobe)
-struct us_ip *create_ip(unsigned long offset, const struct probe_info *probe_i,
+struct us_ip *create_ip(unsigned long offset, const struct probe_info *info,
struct sspt_page *page);
void free_ip(struct us_ip *ip);
int ret;
struct uprobe *up = NULL;
- up = probe_info_get_uprobe(&ip->probe_i, ip);
+ up = probe_info_get_uprobe(ip->info, ip);
if (!up) {
printk(KERN_INFO "SWAP US_MANAGER: failed getting uprobe!\n");
up->task = ip->page->file->proc->task;
up->sm = ip->page->file->proc->sm;
- ret = probe_info_register(&ip->probe_i, ip);
+ ret = probe_info_register(ip->info, ip);
if (ret) {
struct sspt_file *file = ip->page->file;
char *name = file->dentry->d_iname;
switch (flag) {
case US_UNREGS_PROBE:
- probe_info_unregister(&ip->probe_i, ip, 1);
+ probe_info_unregister(ip->info, ip, 1);
break;
case US_DISARM:
- up = probe_info_get_uprobe(&ip->probe_i, ip);
+ up = probe_info_get_uprobe(ip->info, ip);
disarm_uprobe(&up->kp, task);
break;
case US_UNINSTALL:
- probe_info_unregister(&ip->probe_i, ip, 0);
+ probe_info_unregister(ip->info, ip, 0);
break;
default:
panic("incorrect value flag=%d", flag);
static inline void print_ip(struct us_ip *ip, int i)
{
- if (ip->probe_i.probe_type == SWAP_RETPROBE) {
+ if (ip->info->probe_type == SWAP_RETPROBE) {
struct uretprobe *rp = &ip->retprobe;
printk(KERN_INFO "### addr[%2d]=%lx, R_addr=%lx\n",
}
}
- if (flag != US_DISARM)
+ if (flag != US_DISARM) {
file->loaded = 0;
file->vm_start = 0;
file->vm_end = 0;
addr = file->vm_start + page->offset + ip->offset;
ip->orig_addr = addr;
- up = probe_info_get_uprobe(&ip->probe_i, ip);
+ up = probe_info_get_uprobe(ip->info, ip);
up->kp.addr = (kprobe_opcode_t *)addr;
err = sspt_register_usprobe(ip);
static void webprobe_uninit(struct us_ip *ip)
{
- webprobe_cleanup(&ip->probe_i);
+ webprobe_cleanup(ip->info);
}