--- /dev/null
+EXTRA_CFLAGS := $(extra_cflags)
+
+obj-m := swap_writer.o
+swap_writer-y := swap_writer_module.o
--- /dev/null
+board_opt = -DBOARD_@BOARD@
+target_kernel_src = @KERNEL@
+target_arch = @ARCH@
+module_dir = $(realpath $(top_srcdir)/src/modules/writer)
+module_name = swap_writer
+cross_compiler = $(subst gcc,,$(CC))
+
+inlude_opt = -I$(realpath $(top_srcdir)/src/modules/)
+extra_cflags = "$(inlude_opt) $(board_opt)"
+
+all-local:
+ $(MAKE) CROSS_COMPILE=$(cross_compiler) ARCH=$(target_arch) extra_cflags=$(extra_cflags) \
+ $(AM_MAKEFLAGS) -C $(target_kernel_src) M=$(module_dir) modules
+
+ echo "generate data for version patching <$(OBJDUMP)><$(READELF)>"
+ PATH=$(PATH) $(top_srcdir)/src/modules/driver/patchko.sh -g $(module_dir)/$(module_name).ko $(OBJDUMP) $(READELF)
+
+clean-local:
+ $(MAKE) CROSS_COMPILE=$(cross_compiler) ARCH=$(target_arch) $(AM_MAKEFLAGS) -C $(target_kernel_src) M=$(module_dir) clean
+
+install-exec-local:
+ install -m 644 $(module_dir)/$(module_name).ko $(prefix)
+ install -m 644 $(module_dir)/$(module_name).ko.addr $(prefix)
--- /dev/null
+/*
+ * SWAP Writer Module
+ * modules/writer/kernel_operations.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, 2013
+ *
+ * 2013 Alexander Aksenov <a.aksenov@samsung.com>: SWAP Writer implementation
+ *
+ */
+
+/* Kernel functions wrap */
+
+#ifndef __KERNEL_OPERATIONS_H__
+#define __KERNEL_OPERATIONS_H__
+
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+
+/* MESSAGES */
+
+#define print_debug(msg, args...) \
+ printk(KERN_DEBUG "SWAP_WRITER DEBUG : " msg, ##args)
+#define print_msg(msg, args...) \
+ printk(KERN_INFO "SWAP_WRITER : " msg, ##args)
+#define print_warn(msg, args...) \
+ printk(KERN_WARNING "SWAP_WRITER WARNING : " msg, ##args)
+#define print_err(msg, args...) \
+ printk(KERN_ERR "SWAP_WRITER ERROR : " msg, ##args)
+#define print_crit(msg, args...) \
+ printk(KERN_CRIT "SWAP_WRITER CRITICAL : " msg, ##args)
+
+/* ARCH-DEPENDED OPERATIONS */
+
+#ifdef CONFIG_ARM
+
+#define get_regs_ip(regs) regs->ARM_pc
+#define get_regs_ret_func(regs) regs->ARM_lr
+#define get_regs_ret_val(regs) get_regs_r0(regs)
+#define get_regs_r0(regs) regs->ARM_r0
+#define get_regs_r1(regs) regs->ARM_r1
+#define get_regs_r2(regs) regs->ARM_r2
+#define get_regs_r3(regs) regs->ARM_r3
+
+#elif CONFIG_X86_32
+
+#define get_regs_ip(regs) regs->ip
+//TODO Ret function address for x86!
+#define get_regs_ret_func(regs) 0
+#define get_regs_ret_val(regs) 0
+#define get_regs_r0(regs) 0
+#define get_regs_r1(regs) 0
+#define get_regs_r2(regs) 0
+#define get_regs_r3(regs) 0
+
+#endif /* CONFIG_arch */
+
+
+
+#endif /* __KERNEL_OPERATIONS_H__ */
--- /dev/null
+enum _swap_writer_errors {
+ E_SW_SUCCESS = 0 /* Success */
+};
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/dcache.h>
+#include <linux/mm.h>
#include <linux/mm_types.h>
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
-#include <buffer/swap_buffer_module.h>
-#include <buffer/swap_buffer_errors.h>
+#include "../buffer/swap_buffer_module.h"
+#include "../buffer/swap_buffer_errors.h"
#include "swap_writer_module.h"
#include "swap_writer_errors.h"
return E_SW_SUCCESS;
}
+EXPORT_SYMBOL_GPL(init_msg);
void uninit_msg(void)
{
for (i = 0; i < NR_CPUS; ++i)
kfree(cpu_buf[i]);
}
+EXPORT_SYMBOL_GPL(uninit_msg);
static char *get_current_buf(void)
{
}
/* FIXME: check_vma()*/
-#include "../../us_manager/sspt/sspt.h"
+static int check_vma(struct vm_area_struct *vma)
+{
+ return vma->vm_file && !(vma->vm_pgoff != 0 || !(vma->vm_flags & VM_EXEC) || (vma->vm_flags & VM_ACCOUNT) ||
+ !(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) ||
+ !(vma->vm_flags & (VM_READ | VM_MAYREAD)));
+}
+
static char *pack_proc_info_part(char *bin_path, struct mm_struct *mm)
{
struct proc_info_part *pip;
set_len_msg(buf, buf_end);
}
-
+EXPORT_SYMBOL_GPL(proc_info_msg);
u32 cpu_num;
} __attribute__((packed));
-static char *pack_sample(char *payload, struct pt_regs *regs,
- struct task_struct *task)
+static char *pack_sample(char *payload, struct pt_regs *regs)
{
struct sample *s = (struct sample *)payload;
struct task_struct *task = current;
s->pid = task->tgid;
- s->pc_addr = get_current_op(regs);
+ s->pc_addr = get_regs_ip(regs);
s->tid = task->pid;
s->cpu_num = task_cpu(current);
set_len_msg(buf, buf_end);
}
-
+EXPORT_SYMBOL_GPL(sample_msg);
mfe->pid = task->tgid;
mfe->tid = task->pid;
mfe->cpu_num = task_cpu(task);
- mfe->pc_addr = regs->ARM_pc;
- mfe->caller_pc_addr = regs->ARM_lr;
+ mfe->pc_addr = get_regs_ip(regs);
+//TODO ret address for x86!
+ mfe->caller_pc_addr = get_regs_ret_func(regs);
mfe->probe_type = pt;
mfe->probe_sub_type = pst;
mfe->cnt_args = strlen(fmt);
arg_in_regs = cnt < 3 ? cnt : 3;
switch (arg_in_regs) {
case 3:
- args[3] = regs->ARM_r3;
+//TODO x86
+ args[3] = get_regs_r3(regs);
case 2:
- args[2] = regs->ARM_r2;
+//TODO x86
+ args[2] = get_regs_r2(regs);
case 1:
- args[1] = regs->ARM_r1;
+//TODO x86
+ args[1] = get_regs_r1(regs);
case 0:
- args[0] = regs->ARM_r0;
+//TODO x86
+ args[0] = get_regs_r0(regs);
}
/* FIXME: cnt > 4 */
mfe->pid = task->tgid;
mfe->tid = task->pid;
mfe->cpu_num = task_cpu(task);
- mfe->pc_addr = regs->ARM_pc;
- mfe->ret_val = regs->ARM_r0;
+ mfe->pc_addr = get_regs_ip(regs);
+//TODO x86
+ mfe->ret_val = get_regs_r0(regs);
return payload + sizeof(*mfe);
}
struct msg_context_switch *mcs = (struct msg_context_switch *)payload;
struct task_struct *task = current;
- mcs->pc_addr = regs->ARM_pc;
+ mcs->pc_addr = get_regs_ip(regs);
mcs->pid = task->tgid;
mcs->tid = task->pid;
mcs->cpu_num = task_cpu(task);
{
context_switch(regs, MSG_CONTEXT_SWITCH_ENTRY);
}
+EXPORT_SYMBOL_GPL(switch_entry);
void switch_exit(struct pt_regs *regs)
{
context_switch(regs, MSG_CONTEXT_SWITCH_EXIT);
}
-
+EXPORT_SYMBOL_GPL(switch_exit);
set_len_msg(buf, buf_end);
}
+EXPORT_SYMBOL_GPL(error_msg);
static int __init swap_writer_module_init(void)
{
--- /dev/null
+#ifndef _SWAP_MSG_H
+#define _SWAP_MSG_H
+
+#include <linux/types.h>
+
+enum PROBE_TYPE {
+ PT_US = 1,
+ PT_KS = 3
+};
+
+enum PROBE_SUB_TYPE {
+ PST_NONE = 0,
+ PST_KS_FILE = 1,
+ PST_KS_IPC = 2,
+ PST_KS_PROCESS = 3,
+ PST_KS_SIGNAL = 4,
+ PST_KS_NETWORK = 5,
+ PST_KS_DESK = 6
+};
+
+struct pt_regs;
+
+int init_msg(size_t buf_size);
+void uninit_msg(void);
+
+void proc_info_msg(struct task_struct *task);
+void sample_msg(struct pt_regs *regs);
+
+void entry_event(const char *fmt, struct pt_regs *regs,
+ enum PROBE_TYPE pt, enum PROBE_SUB_TYPE pst);
+void exit_event(struct pt_regs *regs);
+
+void switch_entry(struct pt_regs *regs);
+void switch_exit(struct pt_regs *regs);
+
+void error_msg(const char *fmt, ...);
+
+#endif /* _SWAP_MSG_H */