summaryrefslogtreecommitdiff
path: root/writer
diff options
context:
space:
mode:
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>2013-11-06 10:09:33 +0400
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>2013-11-12 17:02:53 +0400
commit4c200caaaba27238f9f90480e87cca0e54f39610 (patch)
treebe710dd9bdc3da811f8397f98014fc047f135c43 /writer
parent5ee9655615c3c3b3542e5792b396339c0930ef16 (diff)
downloadswap-modules-4c200caaaba27238f9f90480e87cca0e54f39610.tar.gz
swap-modules-4c200caaaba27238f9f90480e87cca0e54f39610.tar.bz2
swap-modules-4c200caaaba27238f9f90480e87cca0e54f39610.zip
[PROTO] add return type for exit_event()
Change-Id: I29093f4d50cfb0d84981cee9a65b87b7550dbb25 Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
Diffstat (limited to 'writer')
-rw-r--r--writer/swap_writer_module.c113
-rw-r--r--writer/swap_writer_module.h2
2 files changed, 105 insertions, 10 deletions
diff --git a/writer/swap_writer_module.c b/writer/swap_writer_module.c
index 772fd597..efbd9306 100644
--- a/writer/swap_writer_module.c
+++ b/writer/swap_writer_module.c
@@ -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);
diff --git a/writer/swap_writer_module.h b/writer/swap_writer_module.h
index 510a7117..d709174d 100644
--- a/writer/swap_writer_module.h
+++ b/writer/swap_writer_module.h
@@ -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);