[PROTO] add return type for exit_event()
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Wed, 6 Nov 2013 06:09:33 +0000 (10:09 +0400)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 12 Nov 2013 13:02:53 +0000 (17:02 +0400)
Change-Id: I29093f4d50cfb0d84981cee9a65b87b7550dbb25
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
22 files changed:
ks_features/ks_features.c
parser/msg_buf.c
parser/msg_buf.h
parser/msg_parser.c
parser/msg_parser.h
parser/us_inst.c
uprobe/arch/asm-arm/swap_uprobes.h
uprobe/arch/asm-x86/swap_uprobes.h
us_manager/img/img_file.c
us_manager/img/img_file.h
us_manager/img/img_ip.c
us_manager/img/img_ip.h
us_manager/img/img_proc.c
us_manager/img/img_proc.h
us_manager/pf/pf_group.c
us_manager/pf/pf_group.h
us_manager/sspt/ip.c
us_manager/sspt/ip.h
us_manager/sspt/sspt_file.c
us_manager/sspt/sspt_file.h
writer/swap_writer_module.c
writer/swap_writer_module.h

index a9707e9..f047650 100644 (file)
@@ -113,7 +113,7 @@ static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
                unsigned long func_addr = (unsigned long)rp->kp.addr;
                unsigned long ret_addr = (unsigned long)ri->ret_addr;
 
-               exit_event(regs, func_addr, ret_addr);
+               exit_event('d', regs, func_addr, ret_addr);
        }
 
        return 0;
index 868d9b1..4c12690 100644 (file)
@@ -73,6 +73,19 @@ int is_end_mb(struct msg_buf *mb)
        return mb->ptr == mb->end;
 }
 
+int get_u8(struct msg_buf *mb, u8 *val)
+{
+       if (cmp_mb(mb, sizeof(*val)) < 0)
+               return -EINVAL;
+
+       *val = *((u8 *)mb->ptr);
+       mb->ptr += sizeof(*val);
+
+       print_parse_debug("u8 ->%d;%08X\n", *val, *val);
+
+       return 0;
+}
+
 int get_u32(struct msg_buf *mb, u32 *val)
 {
        if (cmp_mb(mb, sizeof(*val)) < 0)
index 80a1a9b..968f17d 100644 (file)
@@ -41,6 +41,7 @@ int cmp_mb(struct msg_buf *mb, size_t size);
 size_t remained_mb(struct msg_buf *mb);
 int is_end_mb(struct msg_buf *mb);
 
+int get_u8(struct msg_buf *mb, u8 *val);
 int get_u32(struct msg_buf *mb, u32 *val);
 int get_u64(struct msg_buf *mb, u64 *val);
 
index 469d80c..007e423 100644 (file)
@@ -218,6 +218,7 @@ struct func_inst_data *create_func_inst_data(struct msg_buf *mb)
        struct func_inst_data *fi;
        u64 addr;
        char *args;
+       char ret_type;
 
        print_parse_debug("func addr:");
        if (get_u64(mb, &addr)) {
@@ -231,6 +232,12 @@ struct func_inst_data *create_func_inst_data(struct msg_buf *mb)
                return NULL;
        }
 
+       print_parse_debug("funct ret type:");
+       if (get_u8(mb, (u8 *)&ret_type)) {
+               print_err("failed to read data function arguments\n");
+               return NULL;
+       }
+
        fi = kmalloc(sizeof(*fi), GFP_KERNEL);
        if (fi == NULL) {
                print_err("out of memory\n");
@@ -240,6 +247,7 @@ struct func_inst_data *create_func_inst_data(struct msg_buf *mb)
 
        fi->addr = addr;
        fi->args = args;
+       fi->ret_type = ret_type;
 
        return fi;
 }
index 94434d1..6543bb1 100644 (file)
@@ -59,6 +59,7 @@ struct conf_data {
 struct func_inst_data {
        u64 addr;
        char *args;
+       char ret_type;
 };
 
 /* Library struct */
index 3cf4645..e402277 100644 (file)
@@ -67,7 +67,8 @@ static int mod_func_inst(struct func_inst_data *func, struct pf_group *pfg,
 
        switch (mt) {
        case MT_ADD:
-               ret = pf_register_probe(pfg, dentry, func->addr, func->args);
+               ret = pf_register_probe(pfg, dentry, func->addr, func->args,
+                                       func->ret_type);
                break;
        case MT_DEL:
                ret = pf_unregister_probe(pfg, dentry, func->addr);
index 2e0dc53..80ccbdd 100644 (file)
 
 
 struct kprobe;
-struct pt_regs;
 struct task_struct;
 struct uprobe;
 struct uretprobe;
 struct uretprobe_instance;
 
+static inline u32 swap_get_urp_float(struct pt_regs *regs)
+{
+       return regs->ARM_r0;
+}
+
+static inline u64 swap_get_urp_double(struct pt_regs *regs)
+{
+
+       return regs->ARM_r0 | (u64)regs->ARM_r1 << 32;
+}
 
 static inline void arch_ujprobe_return(void)
 {
index 005df43..6aa764c 100644 (file)
@@ -27,6 +27,7 @@
 #ifndef _ARM_SWAP_UPROBES_H
 #define _ARM_SWAP_UPROBES_H
 
+
 #include <kprobe/arch/asm/dbi_kprobes.h>
 
 
@@ -35,6 +36,25 @@ struct uretprobe;
 struct uretprobe_instance;
 
 
+
+static inline u32 swap_get_urp_float(struct pt_regs *regs)
+{
+       u32 st0;
+
+       asm volatile ("fstps    %0" : "=m" (st0));
+
+       return st0;
+}
+
+static inline u64 swap_get_urp_double(struct pt_regs *regs)
+{
+       u64 st1;
+
+       asm volatile ("fstpl    %0" : "=m" (st1));
+
+       return st1;
+}
+
 static inline void arch_ujprobe_return(void)
 {
 }
index e4d05c6..8802512 100644 (file)
@@ -68,7 +68,7 @@ static struct img_ip *find_img_ip(struct img_file *file, unsigned long addr)
 }
 
 int img_file_add_ip(struct img_file *file, unsigned long addr,
-                   const char *args)
+                   const char *args, char ret_type)
 {
        struct img_ip *ip;
 
@@ -78,7 +78,7 @@ int img_file_add_ip(struct img_file *file, unsigned long addr,
                return 0;
        }
 
-       ip = create_img_ip(addr, args);
+       ip = create_img_ip(addr, args, ret_type);
        img_add_ip_by_list(file, ip);
 
        return 0;
index 6cca65b..c5f82fa 100644 (file)
@@ -38,7 +38,7 @@ struct img_file *create_img_file(struct dentry *dentry);
 void free_img_file(struct img_file *ip);
 
 int img_file_add_ip(struct img_file *file, unsigned long addr,
-                   const char *args);
+                   const char *args, char ret_type);
 int img_file_del_ip(struct img_file *file, unsigned long addr);
 
 int img_file_empty(struct img_file *file);
index 13258b0..4f214c3 100644 (file)
@@ -26,7 +26,8 @@
 #include "img_ip.h"
 #include <linux/slab.h>
 
-struct img_ip *create_img_ip(unsigned long addr, const char *args)
+struct img_ip *create_img_ip(unsigned long addr, const char *args,
+                            char ret_type)
 {
        struct img_ip *ip;
        size_t len;
@@ -40,6 +41,8 @@ struct img_ip *create_img_ip(unsigned long addr, const char *args)
        ip->args = kmalloc(len, GFP_KERNEL);
        memcpy(ip->args, args, len);
 
+       ip->ret_type = ret_type;
+
        return ip;
 }
 
index 2f5b4ae..a3676be 100644 (file)
@@ -32,9 +32,11 @@ struct img_ip {
        struct list_head list;                  /* for img_file */
        unsigned long addr;
        char *args;
+       char ret_type;
 };
 
-struct img_ip *create_img_ip(unsigned long addr, const char *args);
+struct img_ip *create_img_ip(unsigned long addr, const char *args,
+                            char ret_type);
 void free_img_ip(struct img_ip *ip);
 
 /* debug */
index 7d4f03f..893a848 100644 (file)
@@ -65,18 +65,18 @@ static struct img_file *find_img_file(struct img_proc *proc, struct dentry *dent
 }
 
 int img_proc_add_ip(struct img_proc *proc, struct dentry *dentry,
-                   unsigned long addr, const char *args)
+                   unsigned long addr, const char *args, char ret_type)
 {
        int ret;
        struct img_file *file;
 
        file = find_img_file(proc, dentry);
        if (file)
-               return img_file_add_ip(file, addr, args);
+               return img_file_add_ip(file, addr, args, ret_type);
 
        file = create_img_file(dentry);
 
-       ret = img_file_add_ip(file, addr, args);
+       ret = img_file_add_ip(file, addr, args, ret_type);
        if (ret) {
                printk("Cannot add ip to img file\n");
                free_img_file(file);
index dad9d66..7da2b0d 100644 (file)
@@ -38,7 +38,7 @@ struct img_proc *create_img_proc(void);
 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);
+                   unsigned long addr, const char *args, char ret_type);
 int img_proc_del_ip(struct img_proc *proc, struct dentry *dentry, unsigned long addr);
 
 /* debug */
index 0cd9053..c3f4b2e 100644 (file)
@@ -86,7 +86,8 @@ void copy_proc_form_img_to_sspt(struct img_proc *i_proc, struct sspt_proc *proc)
                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);
+                       sspt_file_add_ip(file, i_ip->addr, i_ip->args,
+                                        i_ip->ret_type);
        }
 }
 
@@ -203,9 +204,9 @@ 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)
+                     unsigned long offset, const char *args, char ret_type)
 {
-       return img_proc_add_ip(pfg->i_proc, dentry, offset, args);
+       return img_proc_add_ip(pfg->i_proc, dentry, offset, args, ret_type);
 }
 EXPORT_SYMBOL_GPL(pf_register_probe);
 
index 377b59b..bf6438f 100644 (file)
@@ -37,7 +37,7 @@ 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);
+                     unsigned long offset, const char *args, char ret_type);
 int pf_unregister_probe(struct pf_group *pfg, struct dentry *dentry,
                        unsigned long offset);
 
index 89f5a59..4f1d01e 100644 (file)
@@ -56,13 +56,13 @@ static int ret_handler(struct uretprobe_instance *ri, struct pt_regs *regs)
                addr = ip->offset & 0x01 ? addr | 0x01 : addr;
 #endif
 
-               exit_event(regs, addr, ret_addr);
+               exit_event(ip->ret_type, regs, addr, ret_addr);
        }
 
        return 0;
 }
 
-struct us_ip *create_ip(unsigned long offset, const char *args)
+struct us_ip *create_ip(unsigned long offset, const char *args, char ret_type)
 {
        size_t len = strlen(args) + 1;
        struct us_ip *ip = kmalloc(sizeof(*ip) + len, GFP_ATOMIC);
@@ -73,6 +73,7 @@ struct us_ip *create_ip(unsigned long offset, const char *args)
                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);
index 37ed4fa..46bb541 100644 (file)
@@ -36,12 +36,13 @@ struct us_ip {
 
        struct uretprobe retprobe;
        char *args;
+       char ret_type;
 
        unsigned long offset;
 };
 
 
-struct us_ip *create_ip(unsigned long offset, const char *args);
+struct us_ip *create_ip(unsigned long offset, const char *args, char ret_type);
 void free_ip(struct us_ip *ip);
 
 #endif /* __IP__ */
index 86652ab..a20037d 100644 (file)
@@ -137,12 +137,12 @@ struct sspt_page *sspt_find_page_mapped(struct sspt_file *file, unsigned long pa
 }
 
 void sspt_file_add_ip(struct sspt_file *file, unsigned long offset,
-                     const char *args)
+                     const char *args, char ret_type)
 {
        struct sspt_page *page = sspt_find_page_or_new(file, offset & PAGE_MASK);
 
        // FIXME: delete ip
-       struct us_ip *ip = create_ip(offset, args);
+       struct us_ip *ip = create_ip(offset, args, ret_type);
 
        sspt_add_ip(page, ip);
 }
index 2c19e1d..f400682 100644 (file)
@@ -50,7 +50,7 @@ void sspt_file_free(struct sspt_file *file);
 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);
+                     const char *args, char ret_type);
 
 struct sspt_page *sspt_get_page(struct sspt_file *file, unsigned long offset_addr);
 void sspt_put_page(struct sspt_page *page);
index 772fd59..efbd930 100644 (file)
@@ -639,37 +639,132 @@ struct msg_func_exit {
        u64 pc_addr;
        u64 caller_pc_addr;
        u32 cpu_num;
-       u64 ret_val;
+       char ret_val[0];
 } __attribute__((packed));
 
-static char *pack_msg_func_exit(char *payload, struct pt_regs *regs,
-                               unsigned long func_addr,
-                               unsigned long ret_addr)
+static int pack_msg_ret_val(char *buf, int len, char ret_type,
+                             struct pt_regs *regs)
 {
-       struct msg_func_exit *mfe = (struct msg_func_exit *)payload;
+       const char *buf_old = buf;
+       u32 *tmp_u32;
+       u64 *tmp_u64;
+
+       *buf = ret_type;
+       ++buf;
+
+       switch (ret_type) {
+       case 'b': /* 1 byte(bool) */
+               if (len < 1)
+                       return -ENOMEM;
+               *buf = (char)!!get_regs_ret_val(regs);
+               ++buf;
+               break;
+       case 'c': /* 1 byte(char) */
+               if (len < 1)
+                       return -ENOMEM;
+               *buf = (char)get_regs_ret_val(regs);
+               ++buf;
+               break;
+       case 'd': /* 4 byte(int) */
+               if (len < 4)
+                       return -ENOMEM;
+               tmp_u32 = (u32 *)buf;
+               *tmp_u32 = get_regs_ret_val(regs);
+               buf += 4;
+               break;
+       case 'x': /* 8 byte(long) */
+       case 'p': /* 8 byte(pointer) */
+               if (len < 8)
+                       return -ENOMEM;
+               tmp_u64 = (u64 *)buf;
+               *tmp_u64 = (u64)get_regs_ret_val(regs);
+               buf += 8;
+               break;
+       case 's': /* string end with '\0' */
+       {
+               enum { max_str_len = 512 };
+               const char __user *user_s;
+               int len_s, ret;
+
+               user_s = (const char __user *)get_regs_ret_val(regs);
+               len_s = strnlen_user(user_s, max_str_len);
+               if (len < len_s)
+                       return -ENOMEM;
+
+               ret = strncpy_from_user(buf, user_s, len_s);
+               if (ret < 0)
+                       return -EFAULT;
+
+               buf[ret] = '\0';
+               buf += ret + 1;
+       }
+               break;
+       case 'n':
+       case 'v':
+               break;
+       case 'f': /* 4 byte(float) */
+               if (len < 4)
+                       return -ENOMEM;
+               tmp_u32 = (u32 *)buf;
+               *tmp_u32 = swap_get_urp_float(regs);
+               buf += 4;
+               break;
+       case 'w': /* 8 byte(double) */
+               if (len < 8)
+                       return -ENOMEM;
+               tmp_u64 = (u64 *)buf;
+               *tmp_u64 = swap_get_urp_double(regs);
+               buf += 8;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return buf - buf_old;
+}
+
+
+static int pack_msg_func_exit(char *buf, int len, char ret_type,
+                             struct pt_regs *regs, unsigned long func_addr,
+                             unsigned long ret_addr)
+{
+       struct msg_func_exit *mfe = (struct msg_func_exit *)buf;
        struct task_struct *task = current;
+       int ret;
 
        mfe->pid = task->tgid;
        mfe->tid = task->pid;
        mfe->cpu_num = smp_processor_id();
        mfe->pc_addr = func_addr;
        mfe->caller_pc_addr = ret_addr;
-       mfe->ret_val = get_regs_ret_val(regs);
 
-       return payload + sizeof(*mfe);
+       ret = pack_msg_ret_val(mfe->ret_val, len, ret_type, regs);
+       if (ret < 0) {
+               printk("ERROR: packing MSG_FUNCTION_EXIT (ret=%d)\n", ret);
+               return ret;
+       }
+
+       return sizeof(*mfe) + ret;
 }
 
-int exit_event(struct pt_regs *regs, unsigned long func_addr,
+int exit_event(char ret_type, struct pt_regs *regs, unsigned long func_addr,
               unsigned long ret_addr)
 {
        char *buf, *payload, *buf_end;
+       int ret;
 
        if (!check_event(current))
                return 0;
 
        buf = get_current_buf();
        payload = pack_basic_msg_fmt(buf, MSG_FUNCTION_EXIT);
-       buf_end = pack_msg_func_exit(payload, regs, func_addr, ret_addr);
+       /* FIXME: len=1024 */
+       ret = pack_msg_func_exit(payload, 1024, ret_type, regs,
+                                func_addr, ret_addr);
+       if (ret < 0)
+               return ret;
+
+       buf_end = payload + ret;
        set_len_msg(buf, buf_end);
 
        return write_to_buffer(buf);
index 510a711..d709174 100644 (file)
@@ -62,7 +62,7 @@ int sample_msg(struct pt_regs *regs);
 
 int entry_event(const char *fmt, struct pt_regs *regs,
                 enum PROBE_TYPE pt, int sub_type);
-int exit_event(struct pt_regs *regs, unsigned long func_addr,
+int exit_event(char ret_type, struct pt_regs *regs, unsigned long func_addr,
               unsigned long ret_addr);
 
 int switch_entry(struct pt_regs *regs);