summaryrefslogtreecommitdiff
path: root/kprobe
diff options
context:
space:
mode:
authorAlexander Aksenov <a.aksenov@samsung.com>2014-07-03 15:23:28 +0400
committerAlexander Aksenov <a.aksenov@samsung.com>2014-07-11 03:03:05 -0700
commit5c5900144e8624eccdc35fbd518229062f8b8c2e (patch)
tree3ae2425741dfbc0fb86ea59b6d303952c7ef00d9 /kprobe
parent9b460c47abe36554b5d024f2000aaaf9a4613941 (diff)
downloadswap-modules-5c5900144e8624eccdc35fbd518229062f8b8c2e.tar.gz
swap-modules-5c5900144e8624eccdc35fbd518229062f8b8c2e.tar.bz2
swap-modules-5c5900144e8624eccdc35fbd518229062f8b8c2e.zip
[STYLE] Kprobe: doxygen comments
Change-Id: I597197ca4b43d9aa3b2e3af754da0724f9b0d5ef Signed-off-by: Alexander Aksenov <a.aksenov@samsung.com>
Diffstat (limited to 'kprobe')
-rw-r--r--kprobe/arch/asm-arm/swap_kprobes.c193
-rw-r--r--kprobe/arch/asm-arm/swap_kprobes.h158
-rw-r--r--kprobe/arch/asm-arm/trampoline_arm.h21
-rw-r--r--kprobe/arch/asm-x86/swap_kprobes.c149
-rw-r--r--kprobe/arch/asm-x86/swap_kprobes.h83
-rw-r--r--kprobe/swap_kdebug.h26
-rw-r--r--kprobe/swap_kprobes.c162
-rw-r--r--kprobe/swap_kprobes.h207
-rw-r--r--kprobe/swap_kprobes_deps.c65
-rw-r--r--kprobe/swap_kprobes_deps.h23
-rw-r--r--kprobe/swap_slots.c77
-rw-r--r--kprobe/swap_slots.h60
12 files changed, 914 insertions, 310 deletions
diff --git a/kprobe/arch/asm-arm/swap_kprobes.c b/kprobe/arch/asm-arm/swap_kprobes.c
index 0103fe21..c569e362 100644
--- a/kprobe/arch/asm-arm/swap_kprobes.c
+++ b/kprobe/arch/asm-arm/swap_kprobes.c
@@ -1,6 +1,15 @@
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/arch/asm-arm/swap_kprobes.c
+/**
+ * kprobe/arch/asm-arm/swap_kprobes.c
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM/MIPS
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial implementation; Support x86.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @author Alexander Shirshikov <a.shirshikov@samsung.com>: initial implementation for Thumb
+ * @author Stanislav Andreev <s.andreev@samsung.com>: added time debug profiling support; BUG() message fix
+ * @author Stanislav Andreev <s.andreev@samsung.com>: redesign of kprobe functionality -
+ * kprobe_handler() now called via undefined instruction hooks
+ * @author Stanislav Andreev <s.andreev@samsung.com>: hash tables search implemented for uprobes
+ *
+ * @section LICENSE
*
* 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
@@ -16,17 +25,13 @@
* 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, 2006-2010
- *
- * 2006-2007 Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM/MIPS
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
- * 2010-2011 Alexander Shirshikov <a.shirshikov@samsung.com>: initial implementation for Thumb
- * 2012 Stanislav Andreev <s.andreev@samsung.com>: added time debug profiling support; BUG() message fix
- * 2012 Stanislav Andreev <s.andreev@samsung.com>: redesign of kprobe functionality -
- * kprobe_handler() now called via undefined instruction hooks
- * 2012 Stanislav Andreev <s.andreev@samsung.com>: hash tables search implemented for uprobes
+ * @section COPYRIGHT
+ *
+ * Copyright (C) Samsung Electronics, 2006-2014
+ *
+ * @section DESCRIPTION
+ *
+ * SWAP kprobe implementation for ARM architecture.
*/
#include <linux/module.h>
@@ -47,7 +52,7 @@
#include <linux/list.h>
#include <linux/hash.h>
-#define SUPRESS_BUG_MESSAGES
+#define SUPRESS_BUG_MESSAGES /**< Debug-off definition */
#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
@@ -204,6 +209,14 @@ static int make_branch_tarmpoline(unsigned long addr, unsigned long insn,
return ok;
}
+/**
+ * @brief Creates ARM trampoline.
+ *
+ * @param addr Probe address.
+ * @param insn Instuction at this address.
+ * @param tramp Pointer to memory for trampoline.
+ * @return 0 on success, error code on error.
+ */
int arch_make_trampoline_arm(unsigned long addr, unsigned long insn,
unsigned long *tramp)
{
@@ -293,6 +306,13 @@ int arch_make_trampoline_arm(unsigned long addr, unsigned long insn,
}
EXPORT_SYMBOL_GPL(arch_make_trampoline_arm);
+/**
+ * @brief Creates trampoline for kprobe.
+ *
+ * @param p Pointer to kprobe.
+ * @param sm Pointer to slot manager
+ * @return 0 on success, error code on error.
+ */
int swap_arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm)
{
unsigned long addr = (unsigned long)p->addr;
@@ -318,6 +338,13 @@ int swap_arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm)
return 0;
}
+/**
+ * @brief Prepares singlestep for current CPU.
+ *
+ * @param p Pointer to kprobe.
+ * @param regs Pointer to CPU registers data.
+ * @return Void.
+ */
void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
{
int cpu = smp_processor_id();
@@ -331,18 +358,39 @@ void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
}
EXPORT_SYMBOL_GPL(prepare_singlestep);
+/**
+ * @brief Saves previous kprobe.
+ *
+ * @param kcb Pointer to kprobe_ctlblk struct whereto save current kprobe.
+ * @param p_run Pointer to kprobe.
+ * @return Void.
+ */
void save_previous_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *p_run)
{
kcb->prev_kprobe.kp = swap_kprobe_running();
kcb->prev_kprobe.status = kcb->kprobe_status;
}
+/**
+ * @brief Restores previous kprobe.
+ *
+ * @param kcb Pointer to kprobe_ctlblk which contains previous kprobe.
+ * @return Void.
+ */
void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
{
__get_cpu_var(swap_current_kprobe) = kcb->prev_kprobe.kp;
kcb->kprobe_status = kcb->prev_kprobe.status;
}
+/**
+ * @brief Sets currently running kprobe.
+ *
+ * @param p Pointer to currently running kprobe.
+ * @param regs Pointer to CPU registers data.
+ * @param kcb Pointer to kprobe_ctlblk.
+ * @return Void.
+ */
void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb)
{
__get_cpu_var(swap_current_kprobe) = p;
@@ -398,6 +446,13 @@ no_kprobe:
return 1;
}
+/**
+ * @brief Trap handler.
+ *
+ * @param regs Pointer to CPU register data.
+ * @param instr Instruction.
+ * @return kprobe_handler result.
+ */
int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
{
int ret;
@@ -424,6 +479,13 @@ int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
return ret;
}
+/**
+ * @brief Probe pre handler.
+ *
+ * @param p Pointer to fired kprobe.
+ * @param regs Pointer to CPU registers data.
+ * @return 0.
+ */
int swap_setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
struct jprobe *jp = container_of(p, struct jprobe, kp);
@@ -446,11 +508,23 @@ int swap_setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
return 0;
}
+/**
+ * @brief Jprobe return stub.
+ *
+ * @return Void.
+ */
void swap_jprobe_return(void)
{
}
EXPORT_SYMBOL_GPL(swap_jprobe_return);
+/**
+ * @brief Break handler stub.
+ *
+ * @param p Pointer to fired kprobe.
+ * @param regs Pointer to CPU registers data.
+ * @return 0.
+ */
int swap_longjmp_break_handler (struct kprobe *p, struct pt_regs *regs)
{
return 0;
@@ -461,6 +535,12 @@ EXPORT_SYMBOL_GPL(swap_longjmp_break_handler);
extern void mem_text_write_kernel_word(unsigned long *addr, unsigned long word);
#endif
+/**
+ * @brief Arms kprobe.
+ *
+ * @param p Pointer to target kprobe.
+ * @return Void.
+ */
void swap_arch_arm_kprobe(struct kprobe *p)
{
#ifdef CONFIG_STRICT_MEMORY_RWX
@@ -471,6 +551,12 @@ void swap_arch_arm_kprobe(struct kprobe *p)
#endif
}
+/**
+ * @brief Disarms kprobe.
+ *
+ * @param p Pointer to target kprobe.
+ * @return Void.
+ */
void swap_arch_disarm_kprobe(struct kprobe *p)
{
#ifdef CONFIG_STRICT_MEMORY_RWX
@@ -481,6 +567,11 @@ void swap_arch_disarm_kprobe(struct kprobe *p)
#endif
}
+/**
+ * @brief Kretprobe trampoline. Provides jumping to probe handler.
+ *
+ * @return Void.
+ */
void __naked swap_kretprobe_trampoline(void)
{
__asm__ __volatile__ (
@@ -494,6 +585,14 @@ void __naked swap_kretprobe_trampoline(void)
: : : "memory");
}
+/**
+ * @brief Prepares kretprobes, saves ret address, makes function return to
+ * trampoline.
+ *
+ * @param ri Pointer to kretprobe_instance.
+ * @param regs Pointer to CPU registers data.
+ * @return Void.
+ */
void swap_arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
@@ -544,6 +643,11 @@ static struct kj_cb_data * __used kjump_handler(struct kj_cb_data *data)
return data;
}
+/**
+ * @brief Trampoline for kjump kprobes.
+ *
+ * @return Void.
+ */
void kjump_trampoline(void);
__asm(
"kjump_trampoline: \n"
@@ -553,12 +657,27 @@ __asm(
"nop \n" /* for kjump_kprobe */
);
+/**
+ * @brief Gets kjump address.
+ *
+ * @return Kjump address.
+ */
unsigned long get_kjump_addr(void)
{
return (unsigned long)&kjump_trampoline;
}
EXPORT_SYMBOL_GPL(get_kjump_addr);
+/**
+ * @brief Registers callback for kjump probes.
+ *
+ * @param ret_addr Kjump probe return address.
+ * @param regs Pointer to CPU registers data.
+ * @param cb Kjump probe callback of jumper_cb_t type.
+ * @param data Pointer to data that should be saved in kj_cb_data.
+ * @param size Size of the data.
+ * @return 0.
+ */
int set_kjump_cb(unsigned long ret_addr, struct pt_regs *regs,
jumper_cb_t cb, void *data, size_t size)
{
@@ -654,6 +773,12 @@ static unsigned long __used jump_handler(struct cb_data *data)
}
/* FIXME: restore condition flags */
+
+/**
+ * @brief Jumper trampoline.
+ *
+ * @return Void.
+ */
void jump_trampoline(void);
__asm(
"jump_trampoline: \n"
@@ -669,12 +794,27 @@ __asm(
"bx lr \n"
);
+/**
+ * @brief Get jumper address.
+ *
+ * @return Jumper address.
+ */
unsigned long get_jump_addr(void)
{
return (unsigned long)&jump_trampoline;
}
EXPORT_SYMBOL_GPL(get_jump_addr);
+/**
+ * @brief Set jumper probe callback.
+ *
+ * @param ret_addr Jumper probe return address.
+ * @param regs Pointer to CPU registers data.
+ * @param cb Jumper callback of jumper_cb_t type.
+ * @param data Data that should be stored in cb_data.
+ * @param size Size of the data.
+ * @return 0.
+ */
int set_jump_cb(unsigned long ret_addr, struct pt_regs *regs,
jumper_cb_t cb, void *data, size_t size)
{
@@ -698,13 +838,24 @@ EXPORT_SYMBOL_GPL(set_jump_cb);
-
+/**
+ * @brief Registers hook on specified instruction.
+ *
+ * @param hook Pointer to struct undef_hook.
+ * @return Void.
+ */
void swap_register_undef_hook(struct undef_hook *hook)
{
__swap_register_undef_hook(hook);
}
EXPORT_SYMBOL_GPL(swap_register_undef_hook);
+/**
+ * @brief Unregisters hook.
+ *
+ * @param hook Pointer to struct undef_hook.
+ * @return Void.
+ */
void swap_unregister_undef_hook(struct undef_hook *hook)
{
__swap_unregister_undef_hook(hook);
@@ -720,6 +871,11 @@ static struct undef_hook undef_ho_k = {
.fn = kprobe_trap_handler
};
+/**
+ * @brief Initializes kprobes module for ARM arch.
+ *
+ * @return 0 on success, error code on error.
+ */
int swap_arch_init_kprobes(void)
{
int ret;
@@ -749,6 +905,11 @@ int swap_arch_init_kprobes(void)
return 0;
}
+/**
+ * @brief Uninitializes kprobe module.
+ *
+ * @return Void.
+ */
void swap_arch_exit_kprobes(void)
{
kjump_exit();
diff --git a/kprobe/arch/asm-arm/swap_kprobes.h b/kprobe/arch/asm-arm/swap_kprobes.h
index a97420e6..dcfccdc9 100644
--- a/kprobe/arch/asm-arm/swap_kprobes.h
+++ b/kprobe/arch/asm-arm/swap_kprobes.h
@@ -1,9 +1,11 @@
-#ifndef _SWAP_ASM_ARM_KPROBES_H
-#define _SWAP_ASM_ARM_KPROBES_H
-
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/arch/asm-arm/swap_kprobes.h
+/**
+ * @file kprobe/arch/asm-arm/swap_kprobes.h
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM/MIPS
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @author Alexander Shirshikov <a.shirshikov@samsung.com>: initial implementation for Thumb
+ *
+ * @section LICENSE
*
* 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
@@ -19,102 +21,192 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * @section COPYRIGHT
+ *
* Copyright (C) Samsung Electronics, 2006-2010
*
- * 2006-2007 Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM/MIPS
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @section DESCRIPTION
*
- * 2010-2011 Alexander Shirshikov <a.shirshikov@samsung.com>: initial implementation for Thumb
+ * ARM arch-dependent kprobes interface declaration.
*/
+
+#ifndef _SWAP_ASM_ARM_KPROBES_H
+#define _SWAP_ASM_ARM_KPROBES_H
+
#include <linux/sched.h>
#include <linux/compiler.h>
typedef unsigned long kprobe_opcode_t;
#ifdef CONFIG_CPU_S3C2443
+/** Breakpoint instruction */
#define BREAKPOINT_INSTRUCTION 0xe1200070
#else
+/** Breakpoint instruction */
#define BREAKPOINT_INSTRUCTION 0xffffdeff
#endif /* CONFIG_CPU_S3C2443 */
#ifndef KPROBES_RET_PROBE_TRAMP
#ifdef CONFIG_CPU_S3C2443
+/** Undefined instruction */
#define UNDEF_INSTRUCTION 0xe1200071
#else
+/** Undefined instruction */
#define UNDEF_INSTRUCTION 0xfffffffe
#endif /* CONFIG_CPU_S3C2443 */
#endif /* KPROBES_RET_PROBE_TRAMP */
+/** Maximum insn size */
#define MAX_INSN_SIZE 1
+/** Uprobes trampoline length */
#define UPROBES_TRAMP_LEN 9 * 4
-# define UPROBES_TRAMP_INSN_IDX 2
-# define UPROBES_TRAMP_SS_BREAK_IDX 4
-# define UPROBES_TRAMP_RET_BREAK_IDX 5
+/** Uprobes trampoline insn idx */
+#define UPROBES_TRAMP_INSN_IDX 2
+/** Uprobes trampoline ss break idx */
+#define UPROBES_TRAMP_SS_BREAK_IDX 4
+/** Uprobes trampoline ret break idx */
+#define UPROBES_TRAMP_RET_BREAK_IDX 5
+/** Kprobes trampoline length */
#define KPROBES_TRAMP_LEN 9 * 4
+/** Kprobes trampoline insn idx */
# define KPROBES_TRAMP_INSN_IDX UPROBES_TRAMP_INSN_IDX
+/** Kprobes trampoline ss break idx */
# define KPROBES_TRAMP_SS_BREAK_IDX UPROBES_TRAMP_SS_BREAK_IDX
/* TODO: remove (not needed for kprobe) */
# define KPROBES_TRAMP_RET_BREAK_IDX UPROBES_TRAMP_RET_BREAK_IDX
+/** User register offset */
#define UREGS_OFFSET 8
+/**
+ * @struct prev_kprobe
+ * @brief Stores previous kprobe.
+ * @var prev_kprobe::kp
+ * Pointer to kprobe struct.
+ * @var prev_kprobe::status
+ * Kprobe status.
+ */
struct prev_kprobe {
struct kprobe *kp;
unsigned long status;
};
+/**
+ * @brief Gets task pc.
+ *
+ * @param p Pointer to task_struct
+ * @return Value in pc.
+ */
static inline unsigned long arch_get_task_pc(struct task_struct *p)
{
return task_thread_info(p)->cpu_context.pc;
}
+/**
+ * @brief Sets task pc.
+ *
+ * @param p Pointer to task_struct.
+ * @param val Value that should be set.
+ * @return Void.
+ */
static inline void arch_set_task_pc(struct task_struct *p, unsigned long val)
{
task_thread_info(p)->cpu_context.pc = val;
}
+/**
+ * @brief Gets syscall registers.
+ *
+ * @param sp Pointer to stack.
+ * @return Pointer to CPU regs data.
+ */
static inline struct pt_regs *swap_get_syscall_uregs(unsigned long sp)
{
return (struct pt_regs *)(sp + UREGS_OFFSET);
}
+/**
+ * @brief Gets stack pointer.
+ *
+ * @param regs Pointer to CPU registers data.
+ * @return Stack address.
+ */
static inline unsigned long swap_get_stack_ptr(struct pt_regs *regs)
{
return regs->ARM_sp;
}
+/**
+ * @brief Gets instruction pointer.
+ *
+ * @param regs Pointer to CPU registers data.
+ * @return Pointer to pc.
+ */
static inline unsigned long swap_get_instr_ptr(struct pt_regs *regs)
{
return regs->ARM_pc;
}
+/**
+ * @brief Sets instruction pointer.
+ *
+ * @param regs Pointer to CPU registers data.
+ * @param val Address that should be stored in pc.
+ * @return Void.
+ */
static inline void swap_set_instr_ptr(struct pt_regs *regs, unsigned long val)
{
regs->ARM_pc = val;
}
+/**
+ * @brief Gets return address.
+ *
+ * @param regs Pointer to CPU registers data.
+ * @return Return address.
+ */
static inline unsigned long swap_get_ret_addr(struct pt_regs *regs)
{
return regs->ARM_lr;
}
+/**
+ * @brief Sets return address.
+ *
+ * @param regs Pointer to CPU registers data.
+ * @param val New return address.
+ * @return Void.
+ */
static inline void swap_set_ret_addr(struct pt_regs *regs, unsigned long val)
{
regs->ARM_lr = val;
}
+/**
+ * @brief Gets specified argument.
+ *
+ * @param regs Pointer to CPU registers data.
+ * @param num Number of the argument.
+ * @return Argument value.
+ */
static inline unsigned long swap_get_arg(struct pt_regs *regs, int num)
{
return regs->uregs[num];
}
+/**
+ * @brief Sets specified argument.
+ *
+ * @param regs Pointer to CPU registers data.
+ * @param num Number of the argument.
+ * @param val New argument value.
+ * @return Void.
+ */
static inline void swap_set_arg(struct pt_regs *regs, int num,
unsigned long val)
{
@@ -465,15 +557,28 @@ static inline void swap_set_arg(struct pt_regs *regs, int num,
# define THUMB2_INSN_REG_RM(insn) ((insn & 0x000f0000) >> 16)
-/* per-cpu kprobe control block */
+
+
+/**
+ * @struct kprobe_ctlblk
+ * @brief Per-cpu kprobe control block.
+ * @var kprobe_ctlblk::kprobe_status
+ * Kprobe status.
+ * @var kprobe_ctlblk::prev_kprobe
+ * Previous kprobe.
+ */
struct kprobe_ctlblk {
unsigned long kprobe_status;
struct prev_kprobe prev_kprobe;
};
-/* Architecture specific copy of original instruction */
+/**
+ * @struct arch_specific_insn
+ * @brief Architecture specific copy of original instruction.
+ * @var arch_specific_insn::insn
+ * Copy of the original instruction.
+ */
struct arch_specific_insn {
- /* copy of the original instruction */
kprobe_opcode_t *insn;
};
@@ -484,6 +589,11 @@ struct undef_hook;
void swap_register_undef_hook(struct undef_hook *hook);
void swap_unregister_undef_hook(struct undef_hook *hook);
+/**
+ * @brief Arch-dependend module deps initialization stub.
+ *
+ * @return 0.
+ */
static inline int arch_init_module_deps(void)
{
return 0;
@@ -511,6 +621,13 @@ void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ct
void __naked swap_kretprobe_trampoline(void);
+/**
+ * @brief Gets arguments of kernel functions.
+ *
+ * @param regs Pointer to CPU registers data.
+ * @param n Number of the argument.
+ * @return Argument value.
+ */
static inline unsigned long swap_get_karg(struct pt_regs *regs, unsigned long n)
{
switch (n) {
@@ -527,6 +644,13 @@ static inline unsigned long swap_get_karg(struct pt_regs *regs, unsigned long n)
return *((unsigned long *)regs->ARM_sp + n - 4);
}
+/**
+ * @brief swap_get_karg wrapper.
+ *
+ * @param regs Pointer to CPU registers data.
+ * @param n Number of the argument.
+ * @return Argument value.
+ */
static inline unsigned long swap_get_sarg(struct pt_regs *regs, unsigned long n)
{
return swap_get_karg(regs, n);
diff --git a/kprobe/arch/asm-arm/trampoline_arm.h b/kprobe/arch/asm-arm/trampoline_arm.h
index f507f4a4..257aca8c 100644
--- a/kprobe/arch/asm-arm/trampoline_arm.h
+++ b/kprobe/arch/asm-arm/trampoline_arm.h
@@ -1,6 +1,12 @@
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/arch/asm-arm/trampoline_arm.h
+/**
+ * @file kprobe/arch/asm-arm/trampoline_arm.h
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM/MIPS
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
+ * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @author Alexander Shirshikov <a.shirshikov@samsung.com>: initial implementation for Thumb
+ *
+ * @section LICENSE
*
* 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
@@ -16,14 +22,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * @section COPYRIGHT
+ *
* Copyright (C) Samsung Electronics, 2006-2010
*
- * 2006-2007 Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM/MIPS
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @section DESCRIPTION
*
- * 2010-2011 Alexander Shirshikov <a.shirshikov@samsung.com>: initial implementation for Thumb
+ * Provides intefrace for trampoline_arm.S
*/
#ifndef __ASM_ARM_TRAMPOLINE_ARM_H
diff --git a/kprobe/arch/asm-x86/swap_kprobes.c b/kprobe/arch/asm-x86/swap_kprobes.c
index 3f1226ab..813d0231 100644
--- a/kprobe/arch/asm-x86/swap_kprobes.c
+++ b/kprobe/arch/asm-x86/swap_kprobes.c
@@ -1,6 +1,11 @@
-/*
- * Kernel Probes (KProbes)
- * arch/x86/kernel/kprobes.c
+/**
+ * arch/asm-x86/swap_kprobes.c
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial implementation;
+ * Support x86/ARM/MIPS for both user and kernel spaces.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @author Stanislav Andreev <s.andreev@samsung.com>: added time debug profiling support; BUG() message fix
+ *
+ * @section LICENSE
*
* 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
@@ -16,33 +21,13 @@
* 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) IBM Corporation, 2002, 2004
- */
-
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/arch/asm-x86/swap_kprobes.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.
+ * @section COPYRIGHT
*
- * 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) IBM Corporation, 2002, 2004
*
- * Copyright (C) Samsung Electronics, 2006-2010
+ * @section DESCRIPTION
*
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
- * 2012 Stanislav Andreev <s.andreev@samsung.com>: added time debug profiling support; BUG() message fix
+ * SWAP krpobes arch-dependend part for x86.
*/
#include<linux/module.h>
@@ -54,7 +39,7 @@
#include <kprobe/swap_kdebug.h>
#include <kprobe/swap_slots.h>
#include <kprobe/swap_kprobes_deps.h>
-#define SUPRESS_BUG_MESSAGES
+#define SUPRESS_BUG_MESSAGES /**< Debug-off definition. */
extern struct kprobe * per_cpu__current_kprobe;
extern struct kprobe * per_cpu__current_kprobe;
@@ -66,6 +51,7 @@ static void *(*swap_text_poke)(void *addr, const void *opcode, size_t len);
static void (*swap_show_registers)(struct pt_regs * regs);
+/** Stack address. */
#define stack_addr(regs) ((unsigned long *)kernel_stack_pointer(regs))
/*
@@ -126,8 +112,11 @@ static __always_inline void set_jmp_op (void *from, void *to)
jop->op = RELATIVEJUMP_INSTRUCTION;
}
-/*
- * returns non-zero if opcodes can be boosted.
+/**
+ * @brief Check if opcode can be boosted.
+ *
+ * @param opcodes Opcode to check.
+ * @return Non-zero if opcode can be boosted.
*/
int swap_can_boost(kprobe_opcode_t *opcodes)
{
@@ -227,6 +216,13 @@ static int is_IF_modifier (kprobe_opcode_t opcode)
return 0;
}
+/**
+ * @brief Creates trampoline for kprobe.
+ *
+ * @param p Pointer to kprobe.
+ * @param sm Pointer to slot manager
+ * @return 0 on success, error code on error.
+ */
int swap_arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm)
{
/* insn: must be on special executable page on i386. */
@@ -242,6 +238,13 @@ int swap_arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm)
return 0;
}
+/**
+ * @brief Prepares singlestep for current CPU.
+ *
+ * @param p Pointer to kprobe.
+ * @param regs Pointer to CPU registers data.
+ * @return Void.
+ */
void prepare_singlestep (struct kprobe *p, struct pt_regs *regs)
{
int cpu = smp_processor_id();
@@ -265,6 +268,13 @@ void prepare_singlestep (struct kprobe *p, struct pt_regs *regs)
}
EXPORT_SYMBOL_GPL(prepare_singlestep);
+/**
+ * @brief Saves previous kprobe.
+ *
+ * @param kcb Pointer to kprobe_ctlblk struct whereto save current kprobe.
+ * @param p_run Pointer to kprobe.
+ * @return Void.
+ */
void save_previous_kprobe (struct kprobe_ctlblk *kcb, struct kprobe *cur_p)
{
if (kcb->prev_kprobe.kp != NULL)
@@ -280,6 +290,12 @@ void save_previous_kprobe (struct kprobe_ctlblk *kcb, struct kprobe *cur_p)
}
+/**
+ * @brief Restores previous kprobe.
+ *
+ * @param kcb Pointer to kprobe_ctlblk which contains previous kprobe.
+ * @return Void.
+ */
void restore_previous_kprobe (struct kprobe_ctlblk *kcb)
{
__get_cpu_var(swap_current_kprobe) = kcb->prev_kprobe.kp;
@@ -288,6 +304,14 @@ void restore_previous_kprobe (struct kprobe_ctlblk *kcb)
kcb->prev_kprobe.status = 0;
}
+/**
+ * @brief Sets currently running kprobe.
+ *
+ * @param p Pointer to currently running kprobe.
+ * @param regs Pointer to CPU registers data.
+ * @param kcb Pointer to kprobe_ctlblk.
+ * @return Void.
+ */
void set_current_kprobe (struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb)
{
__get_cpu_var(swap_current_kprobe) = p;
@@ -297,6 +321,12 @@ void set_current_kprobe (struct kprobe *p, struct pt_regs *regs, struct kprobe_c
kcb->kprobe_saved_eflags &= ~IF_MASK;
}
+/**
+ * @brief Kprobe handler.
+ *
+ * @param regs Pointer to CPU register data.
+ * @return 1 on success.
+ */
int kprobe_handler (struct pt_regs *regs)
{
struct kprobe *p = 0;
@@ -452,6 +482,13 @@ no_kprobe:
return ret;
}
+/**
+ * @brief Probe pre handler.
+ *
+ * @param p Pointer to fired kprobe.
+ * @param regs Pointer to CPU registers data.
+ * @return 0.
+ */
int swap_setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
struct jprobe *jp = container_of (p, struct jprobe, kp);
@@ -487,8 +524,18 @@ int swap_setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
return 1;
}
+/**
+ * @brief Jprobe return end.
+ *
+ * @return Void.
+ */
void swap_jprobe_return_end(void);
+/**
+ * @brief Jprobe return code.
+ *
+ * @return Void.
+ */
void swap_jprobe_return(void)
{
struct kprobe_ctlblk *kcb = swap_get_kprobe_ctlblk();
@@ -763,6 +810,13 @@ static struct notifier_block kprobe_exceptions_nb = {
.priority = INT_MAX
};
+/**
+ * @brief Longjump break handler.
+ *
+ * @param p Pointer to fired kprobe.
+ * @param regs Pointer to CPU registers data.
+ * @return 0 on success.
+ */
int swap_longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
struct kprobe_ctlblk *kcb = swap_get_kprobe_ctlblk();
@@ -794,12 +848,24 @@ int swap_longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
return 0;
}
+/**
+ * @brief Arms kprobe.
+ *
+ * @param p Pointer to target kprobe.
+ * @return Void.
+ */
void swap_arch_arm_kprobe(struct kprobe *p)
{
swap_text_poke(p->addr,
((unsigned char[]){BREAKPOINT_INSTRUCTION}), 1);
}
+/**
+ * @brief Disarms kprobe.
+ *
+ * @param p Pointer to target kprobe.
+ * @return Void.
+ */
void swap_arch_disarm_kprobe(struct kprobe *p)
{
swap_text_poke(p->addr, &p->opcode, 1);
@@ -810,6 +876,14 @@ static __used void *trampoline_probe_handler_x86(struct pt_regs *regs)
return (void *)trampoline_probe_handler(NULL, regs);
}
+/**
+ * @brief Prepares kretprobes, saves ret address, makes function return to
+ * trampoline.
+ *
+ * @param ri Pointer to kretprobe_instance.
+ * @param regs Pointer to CPU registers data.
+ * @return Void.
+ */
void swap_arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
@@ -830,6 +904,11 @@ void swap_arch_prepare_kretprobe(struct kretprobe_instance *ri,
*ptr_ret_addr = (unsigned long)&swap_kretprobe_trampoline;
}
+/**
+ * @brief Initializes x86 module deps.
+ *
+ * @return 0 on success, negative error code on error.
+ */
int arch_init_module_deps()
{
const char *sym;
@@ -860,11 +939,21 @@ not_found:
return -ESRCH;
}
+/**
+ * @brief Initializes kprobes module for ARM arch.
+ *
+ * @return 0 on success, error code on error.
+ */
int swap_arch_init_kprobes(void)
{
return register_die_notifier (&kprobe_exceptions_nb);
}
+/**
+ * @brief Uninitializes kprobe module.
+ *
+ * @return Void.
+ */
void swap_arch_exit_kprobes(void)
{
unregister_die_notifier (&kprobe_exceptions_nb);
diff --git a/kprobe/arch/asm-x86/swap_kprobes.h b/kprobe/arch/asm-x86/swap_kprobes.h
index 1cf5a77d..c7b06937 100644
--- a/kprobe/arch/asm-x86/swap_kprobes.h
+++ b/kprobe/arch/asm-x86/swap_kprobes.h
@@ -1,30 +1,10 @@
-#ifndef _SWAP_ASM_X86_KPROBES_H
-#define _SWAP_ASM_X86_KPROBES_H
-
-/*
- * Kernel Probes (KProbes)
- * include/linux/kprobes.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.
+/**
+ * @file kprobe/arch/asm-x86/swap_kprobes.h
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial implementation;
+ * Support x86/ARM/MIPS for both user and kernel spaces.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
*
- * Copyright (C) IBM Corporation, 2002, 2004
- */
-
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/arch/asm-x86/swap_kprobes.c
+ * @section LICENSE
*
* 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
@@ -40,18 +20,26 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * @section COPYRIGHT
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
* Copyright (C) Samsung Electronics, 2006-2010
*
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @section DESCRIPTION
*
-
+ * Arch-dependent kprobes interface for x86 arch.
*/
+#ifndef _SWAP_ASM_X86_KPROBES_H
+#define _SWAP_ASM_X86_KPROBES_H
+
+
#include <linux/version.h>
#include <kprobe/swap_kprobes_deps.h>
+/**
+ * @brief Opcode type.
+ */
typedef u8 kprobe_opcode_t;
#define BREAKPOINT_INSTRUCTION 0xcc
@@ -177,12 +165,27 @@ static inline int swap_fp_backtrace(struct task_struct *task,
return i;
}
+/**
+ * @struct prev_kprobe
+ * @brief Stores previous kprobe.
+ * @var prev_kprobe::kp
+ * Pointer to kprobe struct.
+ * @var prev_kprobe::status
+ * Kprobe status.
+ */
struct prev_kprobe {
struct kprobe *kp;
unsigned long status;
};
-/* per-cpu kprobe control block */
+/**
+ * @struct kprobe_ctlblk
+ * @brief Per-cpu kprobe control block.
+ * @var kprobe_ctlblk::kprobe_status
+ * Kprobe status.
+ * @var kprobe_ctlblk::prev_kprobe
+ * Previous kprobe.
+ */
struct kprobe_ctlblk {
unsigned long kprobe_status;
struct prev_kprobe prev_kprobe;
@@ -194,17 +197,23 @@ struct kprobe_ctlblk {
};
-/* Architecture specific copy of original instruction */
+/**
+ * @struct arch_specific_insn
+ * @brief Architecture specific copy of original instruction.
+ * @var arch_specific_insn::insn
+ * Copy of the original instruction.
+ * @var arch_specific_insn::boostable
+ * If this flag is not 0, this kprobe can be boost when its
+ * post_handler and break_handler is not set.
+ */
struct arch_specific_insn {
- /* copy of the original instruction */
kprobe_opcode_t *insn;
- /*
- * If this flag is not 0, this kprobe can be boost when its
- * post_handler and break_handler is not set.
- */
int boostable;
};
+/**
+ * @brief Entry point.
+ */
typedef kprobe_opcode_t (*entry_point_t) (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int arch_init_module_deps(void);
diff --git a/kprobe/swap_kdebug.h b/kprobe/swap_kdebug.h
index 8c7b3ff7..4e76cb92 100644
--- a/kprobe/swap_kdebug.h
+++ b/kprobe/swap_kdebug.h
@@ -1,9 +1,10 @@
-#ifndef _SWAP_KPROBE_DEBUG_H
-#define _SWAP_KPROBE_DEBUG_H
-
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/swap_kdebug.h
+/**
+ * @file kprobe/swap_kdebug.h
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial implementation;
+ * Support x86/ARM/MIPS for both user and kernel spaces.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ *
+ * @section LICENSE
*
* 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
@@ -19,13 +20,18 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * @section COPYRIGHT
+ *
* Copyright (C) Samsung Electronics, 2006-2010
*
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @section DESCRIPTION
*
-*/
+ * Header for debug purposes.
+ */
+
+
+#ifndef _SWAP_KPROBE_DEBUG_H
+#define _SWAP_KPROBE_DEBUG_H
//#define _DEBUG
diff --git a/kprobe/swap_kprobes.c b/kprobe/swap_kprobes.c
index ef545a68..b5983e4f 100644
--- a/kprobe/swap_kprobes.c
+++ b/kprobe/swap_kprobes.c
@@ -1,27 +1,11 @@
-/*
- * Kernel Probes (KProbes)
- * kernel/kprobes.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.
+/**
+ * kprobe/swap_kprobes.c
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM and MIPS
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial implementation;
+ * Support x86/ARM/MIPS for both user and kernel spaces.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
*
- * Copyright (C) IBM Corporation, 2002, 2004
- */
-
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/swap_kprobes.h
+ * @section LICENSE
*
* 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
@@ -37,16 +21,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * @section COPYRIGHT
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
* Copyright (C) Samsung Electronics, 2006-2010
*
- * 2006-2007 Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM and MIPS
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @section DESCRIPTION
*
+ * SWAP kprobe implementation. Dynamic kernel functions instrumentation.
*/
-
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
#include <linux/config.h>
@@ -65,13 +49,21 @@
#include "swap_kprobes.h"
#include "swap_kprobes_deps.h"
-
+/**
+ * @var sched_addr
+ * @brief Scheduler address.
+ */
unsigned long sched_addr;
static unsigned long exit_addr;
static unsigned long do_group_exit_addr;
static unsigned long sys_exit_group_addr;
static unsigned long sys_exit_addr;
+/**
+ * @var sm
+ * @brief Current slot manager. Slots are the places where trampolines are
+ * located.
+ */
struct slot_manager sm;
DEFINE_PER_CPU(struct kprobe *, swap_current_kprobe) = NULL;
@@ -83,6 +75,10 @@ static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
+/**
+ * @var kprobe_count
+ * @brief Count of kprobes.
+ */
atomic_t kprobe_count;
EXPORT_SYMBOL_GPL(kprobe_count);
@@ -159,17 +155,31 @@ static inline void reset_kprobe_instance(void)
__get_cpu_var(kprobe_instance) = NULL;
}
-/* swap_kprobe_running() will just return the current_kprobe on this CPU */
+/**
+ * @brief Gets the current kprobe on this CPU.
+ *
+ * @return Pointer to the current kprobe.
+ */
struct kprobe *swap_kprobe_running(void)
{
return __get_cpu_var(swap_current_kprobe);
}
+/**
+ * @brief Sets the current kprobe to NULL.
+ *
+ * @return Void.
+ */
void swap_reset_current_kprobe(void)
{
__get_cpu_var(swap_current_kprobe) = NULL;
}
+/**
+ * @brief Gets kprobe_ctlblk for the current CPU.
+ *
+ * @return Current CPU struct kprobe_ctlblk.
+ */
struct kprobe_ctlblk *swap_get_kprobe_ctlblk(void)
{
return &__get_cpu_var(kprobe_ctlblk);
@@ -181,6 +191,13 @@ struct kprobe_ctlblk *swap_get_kprobe_ctlblk(void)
* OR
* - with preemption disabled - from arch/xxx/kernel/kprobes.c
*/
+
+/**
+ * @brief Gets kprobe.
+ *
+ * @param addr Probe address.
+ * @return Kprobe for addr.
+ */
struct kprobe *swap_get_kprobe(void *addr)
{
struct hlist_head *head;
@@ -265,7 +282,12 @@ static int aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
return ret;
}
-/* Walks the list and increments nmissed count for multiprobe case */
+/**
+ * @brief Walks the list and increments nmissed count for multiprobe case.
+ *
+ * @param p Pointer to the missed kprobe.
+ * @return Void.
+ */
void swap_kprobes_inc_nmissed_count(struct kprobe *p)
{
struct kprobe *kp;
@@ -495,6 +517,12 @@ static void remove_kprobe(struct kprobe *p)
swap_slot_free(&sm, p->ainsn.insn);
}
+/**
+ * @brief Registers kprobe.
+ *
+ * @param p Pointer to the target kprobe.
+ * @return 0 on success, error code on error.
+ */
int swap_register_kprobe(struct kprobe *p)
{
struct kprobe *old_p;
@@ -581,6 +609,12 @@ static void swap_unregister_valid_kprobe(struct kprobe *p, struct kprobe *old_p)
p->addr = NULL;
}
+/**
+ * @brief Unregistes kprobe.
+ *
+ * @param kp Pointer to the target kprobe.
+ * @return Void.
+ */
void swap_unregister_kprobe(struct kprobe *kp)
{
struct kprobe *old_p, *list_p;
@@ -602,6 +636,12 @@ unreg_valid_kprobe:
}
EXPORT_SYMBOL_GPL(swap_unregister_kprobe);
+/**
+ * @brief Registers jprobe.
+ *
+ * @param jp Pointer to the target jprobe.
+ * @return swap_register_kprobe result.
+ */
int swap_register_jprobe(struct jprobe *jp)
{
/* Todo: Verify probepoint is a function entry point */
@@ -612,6 +652,12 @@ int swap_register_jprobe(struct jprobe *jp)
}
EXPORT_SYMBOL_GPL(swap_register_jprobe);
+/**
+ * @brief Unregisters jprobe.
+ *
+ * @param jp Pointer to the target jprobe.
+ * @return Void.
+ */
void swap_unregister_jprobe(struct jprobe *jp)
{
swap_unregister_kprobe(&jp->kp);
@@ -652,6 +698,13 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
return 0;
}
+/**
+ * @brief Trampoline probe handler.
+ *
+ * @param p Pointer to the fired kprobe.
+ * @param regs Pointer to CPU registers data.
+ * @return orig_ret_address
+ */
int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
{
struct kretprobe_instance *ri = NULL;
@@ -776,6 +829,12 @@ static int alloc_nodes_kretprobe(struct kretprobe *rp)
return 0;
}
+/**
+ * @brief Registers kretprobes.
+ *
+ * @param rp Pointer to the target kretprobe.
+ * @return 0 on success, error code on error.
+ */
int swap_register_kretprobe(struct kretprobe *rp)
{
int ret = 0;
@@ -848,6 +907,14 @@ static void swap_disarm_krp(struct kretprobe *rp)
}
}
+/**
+ * @brief Kretprobes unregister top. Unregisters kprobes.
+ *
+ * @param rps Pointer to the array of pointers to the target kretprobes.
+ * @param size Size of rps array.
+ * @param rp_disarm Disarm flag. If set kretprobe is disarmed.
+ * @return Void.
+ */
void swap_unregister_kretprobes_top(struct kretprobe **rps, size_t size,
int rp_disarm)
{
@@ -864,12 +931,25 @@ void swap_unregister_kretprobes_top(struct kretprobe **rps, size_t size,
}
EXPORT_SYMBOL_GPL(swap_unregister_kretprobes_top);
+/**
+ * @brief swap_unregister_kretprobes_top wrapper for a single kretprobe.
+ *
+ * @param rp Pointer to the target kretprobe.
+ * @param rp_disarm Disarm flag.
+ * @return Void.
+ */
void swap_unregister_kretprobe_top(struct kretprobe *rp, int rp_disarm)
{
swap_unregister_kretprobes_top(&rp, 1, rp_disarm);
}
EXPORT_SYMBOL_GPL(swap_unregister_kretprobe_top);
+/**
+ * @brief Kretprobe unregister bottom. Here is kretprobe memory is released.
+ *
+ * @param rp Pointer to the target kretprobe.
+ * @return Void.
+ */
void swap_unregister_kretprobe_bottom(struct kretprobe *rp)
{
unsigned long flags;
@@ -886,6 +966,13 @@ void swap_unregister_kretprobe_bottom(struct kretprobe *rp)
}
EXPORT_SYMBOL_GPL(swap_unregister_kretprobe_bottom);
+/**
+ * @brief swap_unregister_kretprobe_bottom wrapper for several kretprobes.
+ *
+ * @param rps Pointer to the array of the target kretprobes pointers.
+ * @param size Size of rps array.
+ * @return Void.
+ */
void swap_unregister_kretprobes_bottom(struct kretprobe **rps, size_t size)
{
const size_t end = ((size_t) 0) - 1;
@@ -895,6 +982,13 @@ void swap_unregister_kretprobes_bottom(struct kretprobe **rps, size_t size)
}
EXPORT_SYMBOL_GPL(swap_unregister_kretprobes_bottom);
+/**
+ * @brief Unregisters kretprobes.
+ *
+ * @param rpp Pointer to the array of the target kretprobes pointers.
+ * @param size Size of rpp array.
+ * @return Void.
+ */
void swap_unregister_kretprobes(struct kretprobe **rpp, size_t size)
{
swap_unregister_kretprobes_top(rpp, size, 1);
@@ -906,6 +1000,12 @@ void swap_unregister_kretprobes(struct kretprobe **rpp, size_t size)
}
EXPORT_SYMBOL_GPL(swap_unregister_kretprobes);
+/**
+ * @brief swap_unregister_kretprobes wrapper for a single kretprobe.
+ *
+ * @param rp Pointer to the target kretprobe.
+ * @return Void.
+ */
void swap_unregister_kretprobe(struct kretprobe *rp)
{
swap_unregister_kretprobes(&rp, 1);
diff --git a/kprobe/swap_kprobes.h b/kprobe/swap_kprobes.h
index 5d6aea5f..4e99c603 100644
--- a/kprobe/swap_kprobes.h
+++ b/kprobe/swap_kprobes.h
@@ -1,30 +1,11 @@
-#ifndef _SWAP_KPROBES_H
-#define _SWAP_KPROBES_H
-
-/*
- * Kernel Probes (KProbes)
- * include/linux/kprobes.h
+/**
+ * @file kprobe/swap_kprobes.h
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM and MIPS
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial implementation;
+ * Support x86/ARM/MIPS for both user and kernel spaces.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
*
- * 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) IBM Corporation, 2002, 2004
- */
-
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/swap_kprobes.h
+ * @section LICENSE
*
* 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
@@ -40,16 +21,20 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * @section COPYRIGHT
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
* Copyright (C) Samsung Electronics, 2006-2010
*
- * 2006-2007 Ekaterina Gorelkina <e.gorelkina@samsung.com>: initial implementation for ARM and MIPS
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @section DESCRIPTION
*
+ * SWAP kprobe interface definition.
*/
+#ifndef _SWAP_KPROBES_H
+#define _SWAP_KPROBES_H
+
#include <linux/version.h> // LINUX_VERSION_CODE, KERNEL_VERSION()
#include <linux/notifier.h>
#include <linux/percpu.h>
@@ -69,81 +54,118 @@
/* kprobe_status settings */
+/** Kprobe hit active */
#define KPROBE_HIT_ACTIVE 0x00000001
+/** Kprobe hit ss */
#define KPROBE_HIT_SS 0x00000002
+/** Kprobe reenter */
#define KPROBE_REENTER 0x00000004
+/** Kprobe hit ss done */
#define KPROBE_HIT_SSDONE 0x00000008
+/** High word */
#define HIWORD(x) (((x) & 0xFFFF0000) >> 16)
+/** Low word */
#define LOWORD(x) ((x) & 0x0000FFFF)
+/** Invalid value */
#define INVALID_VALUE 0xFFFFFFFF
+/** Invalid pointer */
#define INVALID_POINTER (void*)INVALID_VALUE
+/** Jprobe entry */
#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry
+/** Retprobe stack depth */
#define RETPROBE_STACK_DEPTH 64
struct kprobe;
struct pt_regs;
struct kretprobe;
struct kretprobe_instance;
+
+/**
+ * @brief Kprobe pre-handler pointer.
+ */
typedef int (*kprobe_pre_handler_t) (struct kprobe *, struct pt_regs *);
+
+/**
+ * @brief Kprobe break handler pointer.
+ */
typedef int (*kprobe_break_handler_t) (struct kprobe *, struct pt_regs *);
+
+/**
+ * @brief Kprobe post handler pointer.
+ */
typedef void (*kprobe_post_handler_t) (struct kprobe *, struct pt_regs *, unsigned long flags);
+
+/**
+ * @brief Kprobe fault handler pointer.
+ */
typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *, int trapnr);
+
+/**
+ * @brief Kretprobe handler pointer.
+ */
typedef int (*kretprobe_handler_t) (struct kretprobe_instance *, struct pt_regs *);
+/**
+ * @struct kprobe
+ * @brief Main kprobe struct.
+ */
struct kprobe
{
- struct hlist_node hlist;
- /*list of probes to search by instruction slot*/
+ struct hlist_node hlist; /**< Hash list.*/
+ /** List of probes to search by instruction slot.*/
struct hlist_node is_hlist;
- /* list of kprobes for multi-handler support */
+ /** List of kprobes for multi-handler support.*/
struct list_head list;
- /* Indicates that the corresponding module has been ref counted */
+ /** Indicates that the corresponding module has been ref counted.*/
unsigned int mod_refcounted;
- /*count the number of times this probe was temporarily disarmed */
+ /** Count the number of times this probe was temporarily disarmed.*/
unsigned long nmissed;
- /* location of the probe point */
+ /** Location of the probe point. */
kprobe_opcode_t *addr;
- /* Allow user to indicate symbol name of the probe point */
+ /** Allow user to indicate symbol name of the probe point.*/
char *symbol_name;
- /* Offset into the symbol */
+ /** Offset into the symbol.*/
unsigned int offset;
- /* Called before addr is executed. */
+ /** Called before addr is executed.*/
kprobe_pre_handler_t pre_handler;
- /* Called after addr is executed, unless... */
+ /** Called after addr is executed, unless...*/
kprobe_post_handler_t post_handler;
- /* ... called if executing addr causes a fault (eg. page fault).
- * Return 1 if it handled fault, otherwise kernel will see it. */
+ /** ... called if executing addr causes a fault (eg. page fault).*/
kprobe_fault_handler_t fault_handler;
- /* ... called if breakpoint trap occurs in probe handler.
- * Return 1 if it handled break, otherwise kernel will see it. */
+ /** Return 1 if it handled fault, otherwise kernel will see it.*/
kprobe_break_handler_t break_handler;
- /* Saved opcode (which has been replaced with breakpoint) */
+ /** Saved opcode (which has been replaced with breakpoint).*/
kprobe_opcode_t opcode;
- /* copy of the original instruction */
+ /** Copy of the original instruction.*/
struct arch_specific_insn ainsn;
- // override single-step target address,
- // may be used to redirect control-flow to arbitrary address after probe point
- // without invocation of original instruction;
- // useful for functions replacement
- // if jprobe.entry should return address of function or NULL
- // if original function should be called
- // not supported for X86, not tested for MIPS
+ /** Override single-step target address, may be used to redirect
+ * control-flow to arbitrary address after probe point without
+ * invocation of original instruction; useful for functions
+ * replacement. If jprobe.entry should return address of function or
+ * NULL if original function should be called.
+ * Not supported for X86, not tested for MIPS. */
kprobe_opcode_t *ss_addr[NR_CPUS];
- // safe/unsafe to use probe
#ifdef CONFIG_ARM
+ /** Safe/unsafe to use probe on ARM.*/
unsigned safe_arm:1;
+ /** Safe/unsafe to use probe on Thumb.*/
unsigned safe_thumb:1;
#endif
};
+/**
+ * @brief Kprobe pre-entry handler pointer.
+ */
typedef unsigned long (*kprobe_pre_entry_handler_t) (void *priv_arg, struct pt_regs * regs);
-/*
- * Special probe type that uses setjmp-longjmp type tricks to resume
+
+/**
+ * @struct jprobe
+ * @brief Special probe type that uses setjmp-longjmp type tricks to resume
* execution at a specified entry with a matching prototype corresponding
* to the probed function - a trick to enable arguments to become
* accessible seamlessly by probe handling logic.
@@ -151,23 +173,28 @@ typedef unsigned long (*kprobe_pre_entry_handler_t) (void *priv_arg, struct pt_r
* Because of the way compilers allocate stack space for local variables
* etc upfront, regardless of sub-scopes within a function, this mirroring
* principle currently works only for probes placed on function entry points.
- */
+ */
struct jprobe
{
- struct kprobe kp;
- // probe handling code to jump to
- kprobe_opcode_t *entry;
- // handler whichw willb bec called before 'entry'
+ struct kprobe kp; /**< This probes kprobe.*/
+ kprobe_opcode_t *entry; /**< Probe handling code to jump to.*/
+ /** Handler which will be called before 'entry'. */
kprobe_pre_entry_handler_t pre_entry;
- void *priv_arg;
+ void *priv_arg; /**< Private args.*/
};
+
+/**
+ * @struct jprobe_instance
+ * @brief Jprobe instance struct.
+ */
struct jprobe_instance
{
// either on free list or used list
- struct hlist_node uflist;
- struct hlist_node hlist;
- struct jprobe *jp;
+ struct hlist_node uflist; /**< Jprobes hash list. */
+ struct hlist_node hlist; /**< Jprobes hash list. */
+ struct jprobe *jp; /**< Pointer to the target jprobe. */
+ /** Pointer to the target task_struct. */
struct task_struct *task;
};
@@ -175,45 +202,49 @@ struct jprobe_instance
-/*
- * Function-return probe -
- * Note:
- * User needs to provide a handler function, and initialize maxactive.
- * maxactive - The maximum number of instances of the probed function that
- * can be active concurrently.
- * nmissed - tracks the number of times the probed function's return was
- * ignored, due to maxactive being too low.
- *
+/**
+ * @struct kretprobe
+ * @brief Function-return probe
+ * Note: User needs to provide a handler function, and initialize maxactive.
*/
struct kretprobe
{
- struct kprobe kp;
- kretprobe_handler_t handler;
- kretprobe_handler_t entry_handler;
+ struct kprobe kp; /**< Kprobe of this kretprobe.*/
+ kretprobe_handler_t handler; /**< Handler of this kretprobe.*/
+ kretprobe_handler_t entry_handler; /**< Entry handler of this kretprobe.*/
+ /** The maximum number of instances of the probed function that can be
+ * active concurrently. */
int maxactive;
+ /** Tracks the number of times the probed function's return was ignored,
+ * due to maxactive being too low. */
int nmissed;
- size_t data_size;
+ size_t data_size; /**< Size of the data. */
+ /** List of this probe's free_instances. */
struct hlist_head free_instances;
+ /** List of this probe's used_instances. */
struct hlist_head used_instances;
#ifdef CONFIG_ARM
- // probe with noreturn (bl,blx)
- unsigned arm_noret:1;
- unsigned thumb_noret:1;
+ unsigned arm_noret:1; /**< No-return flag for ARM.*/
+ unsigned thumb_noret:1; /**< No-return flag for Thumb.*/
#endif
};
+/**
+ * @struct kretprobe_instance
+ * @brief Instance of kretprobe.
+ */
struct kretprobe_instance
{
// either on free list or used list
- struct hlist_node uflist;
- struct hlist_node hlist;
- struct kretprobe *rp;
- unsigned long *ret_addr;
- unsigned long *sp;
- struct task_struct *task;
- char data[0];
+ struct hlist_node uflist; /**< Kretprobe hash list.*/
+ struct hlist_node hlist; /**< Kretprobe hash list.*/
+ struct kretprobe *rp; /**< Pointer to this instance's kretprobe.*/
+ unsigned long *ret_addr; /**< Return address.*/
+ unsigned long *sp; /**< Stack pointer.*/
+ struct task_struct *task; /**< Pointer to the target task_struct.*/
+ char data[0]; /**< Pointer to data.*/
};
diff --git a/kprobe/swap_kprobes_deps.c b/kprobe/swap_kprobes_deps.c
index b199a485..6334434b 100644
--- a/kprobe/swap_kprobes_deps.c
+++ b/kprobe/swap_kprobes_deps.c
@@ -1,6 +1,10 @@
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/swap_kprobes_deps.h
+/**
+ * kprobe/swap_kprobes_deps.c
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial implementation;
+ * Support x86/ARM/MIPS for both user and kernel spaces.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ *
+ * @section LICENSE
*
* 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
@@ -16,12 +20,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * @section COPYRIGHT
+ *
* Copyright (C) Samsung Electronics, 2006-2010
*
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @section DESCRIPTION
*
+ * SWAP kprobe kernel-dependent dependencies.
*/
#include <linux/module.h>
@@ -304,7 +309,11 @@ IMP_MOD_DEP_WRAPPER (vm_normal_page, vma, addr, pte)
-
+/**
+ * @brief Initializes module dependencies.
+ *
+ * @return 0.
+ */
int init_module_dependencies(void)
{
@@ -432,6 +441,19 @@ static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long add
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+/**
+ * @brief Gets user pages uprobe.
+ *
+ * @param tsk Pointer to the task_struct.
+ * @param mm Pointer to the mm_struct.
+ * @param start Starting address.
+ * @param nr_pages Pages number.
+ * @param gup_flags Flags.
+ * @param pages Pointer to the array of pointers to the target page structs.
+ * @param vmas Pointer to the array of pointers to the target vm_area_struct.
+ * @param nonblocking Pointer to int.
+ * @return negative error code on error, positive result otherwise.
+ */
long __get_user_pages_uprobe(struct task_struct *tsk, struct mm_struct *mm,
unsigned long start, unsigned long nr_pages,
unsigned int gup_flags, struct page **pages,
@@ -1015,6 +1037,19 @@ static int __get_user_pages_uprobe(struct task_struct *tsk, struct mm_struct *mm
#endif
#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
+/**
+ * @brief Gets user pages uprobe.
+ *
+ * @param tsk Pointer to the task_struct.
+ * @param mm Pointer to the mm_struct.
+ * @param start Starting address.
+ * @param len Length.
+ * @param write Write flag.
+ * @param force Force flag.
+ * @param pages Pointer to the array of pointers to the target page structs.
+ * @param vmas Pointer to the array of pointers to the target vm_area_struct.
+ * @return negative error code on error, positive result otherwise.
+ */
int get_user_pages_uprobe(struct task_struct *tsk, struct mm_struct *mm,
unsigned long start, int len, int write, int force,
struct page **pages, struct vm_area_struct **vmas)
@@ -1115,6 +1150,16 @@ static void write_data_current(unsigned long addr, void *buf, int len)
}
#endif
+/**
+ * @brief Read-write task memory.
+ *
+ * @param tsk Pointer to the target task task_struct.
+ * @param addr Address to read-write.
+ * @param buf Pointer to buffer where to put-get data.
+ * @param len Buffer length.
+ * @param write Write flag. If 0 - reading, if 1 - writing.
+ * @return Read-write size, error code on error.
+ */
int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
{
struct mm_struct *mm;
@@ -1193,6 +1238,12 @@ int access_process_vm_atomic(struct task_struct *tsk, unsigned long addr, void *
return buf - old_buf;
}
+/**
+ * @brief Page present.
+ *
+ * @param mm Pointer to the target mm_struct.
+ * @param address Address.
+ */
int page_present (struct mm_struct *mm, unsigned long address)
{
pgd_t *pgd;
diff --git a/kprobe/swap_kprobes_deps.h b/kprobe/swap_kprobes_deps.h
index 06a57e67..70824def 100644
--- a/kprobe/swap_kprobes_deps.h
+++ b/kprobe/swap_kprobes_deps.h
@@ -1,9 +1,10 @@
-#ifndef _SWAP_KPROBES_DEPS_H
-#define _SWAP_KPROBES_DEPS_H
-
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/swap_kprobes_deps.h
+/**
+ * @file kprobe/swap_kprobes_deps.h
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial implementation;
+ * Support x86/ARM/MIPS for both user and kernel spaces.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ *
+ * @section LICENSE
*
* 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
@@ -19,14 +20,18 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * @section COPYRIGHT
+ *
* Copyright (C) Samsung Electronics, 2006-2010
*
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @section DESCRIPTION
*
+ * SWAP kprobe kernel-dependent dependencies.
*/
+#ifndef _SWAP_KPROBES_DEPS_H
+#define _SWAP_KPROBES_DEPS_H
+
#include <linux/version.h> // LINUX_VERSION_CODE, KERNEL_VERSION()
#include <linux/hugetlb.h>
#include <linux/mempolicy.h>
diff --git a/kprobe/swap_slots.c b/kprobe/swap_slots.c
index a54ec5d6..2fcbb754 100644
--- a/kprobe/swap_slots.c
+++ b/kprobe/swap_slots.c
@@ -1,27 +1,11 @@
-/*
- * Kernel Probes (KProbes)
- * kernel/kprobes.c
+/**
+ * kprobe/swap_slots.c
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial implementation;
+ * Support x86/ARM/MIPS for both user and kernel spaces.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @author Vyacheslav Cherkashin <v.cherkashin@samsung.com> new memory allocator for slots
*
- * 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) IBM Corporation, 2002, 2004
- */
-
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/swap_slots.c
+ * @section LICENSE
*
* 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
@@ -37,12 +21,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * @section COPYRIGHT
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
* Copyright (C) Samsung Electronics, 2006-2012
*
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
- * 2012-2013 Vyacheslav Cherkashin <v.cherkashin@samsung.com> new memory allocator for slots
+ * @section DESCRIPTION
+ *
+ * SWAP slots implementation.
*/
@@ -55,6 +41,22 @@
#include "swap_kprobes_deps.h"
+/**
+ * @struct chunk
+ * @brief Chunk of memory for trampolines.
+ * @var chunk::data
+ * Chunk data.
+ * @var chunk::first_available
+ * Index of the first available block.
+ * @var chunk::count_available
+ * Count of the blocks.
+ * @var chunk::lock
+ * Chunk's lock.
+ * @var chunk::size
+ * Count of the blocks in chunk.
+ * @var chunk::index
+ * Pointer to allocated memory.
+ */
struct chunk {
unsigned long *data;
unsigned long first_available;
@@ -65,6 +67,14 @@ struct chunk {
unsigned long *index;
};
+/**
+ * @struct fixed_alloc
+ * @brief Item of fixed allocs list.
+ * @var fixed_alloc::hlist
+ * Fixed alloc hash list node.
+ * @var fixed_alloc::chunk
+ * Chunk.
+ */
struct fixed_alloc
{
struct hlist_node hlist;
@@ -167,6 +177,12 @@ static void free_fixed_alloc(struct slot_manager *sm, struct fixed_alloc *fa)
}
+/**
+ * @brief Allocates slot for slot manager.
+ *
+ * @param[in,out] sm Slot manager that should be filled.
+ * @return Pointer to allocated slot.
+ */
void *swap_slot_alloc(struct slot_manager *sm)
{
void *free_slot;
@@ -190,6 +206,13 @@ void *swap_slot_alloc(struct slot_manager *sm)
}
EXPORT_SYMBOL_GPL(swap_slot_alloc);
+/**
+ * @brief Releases allocated slot.
+ *
+ * @param sm Pointer to the target slot manager.
+ * @param slot Pointer to the target slot.
+ * @return Void.
+ */
void swap_slot_free(struct slot_manager *sm, void *slot)
{
struct fixed_alloc *fa;
diff --git a/kprobe/swap_slots.h b/kprobe/swap_slots.h
index 3e48059a..129a4391 100644
--- a/kprobe/swap_slots.h
+++ b/kprobe/swap_slots.h
@@ -1,30 +1,11 @@
-#ifndef _SWAP_SLOTS_H
-#define _SWAP_SLOTS_H
-
-/*
- * Kernel Probes (KProbes)
- * include/linux/kprobes.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.
+/**
+ * @file kprobe/swap_slots.h
+ * @author Alexey Gerenkov <a.gerenkov@samsung.com> User-Space Probes initial implementation;
+ * Support x86/ARM/MIPS for both user and kernel spaces.
+ * @author Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
+ * @author Vyacheslav Cherkashin <v.cherkashin@samsung.com> new memory allocator for slots
*
- * 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) IBM Corporation, 2002, 2004
- */
-
-/*
- * Dynamic Binary Instrumentation Module based on KProbes
- * modules/kprobe/swap_slots.h
+ * @section LICENSE
*
* 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
@@ -40,16 +21,35 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * @section COPYRIGHT
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
* Copyright (C) Samsung Electronics, 2006-2010
*
- * 2008-2009 Alexey Gerenkov <a.gerenkov@samsung.com> User-Space
- * Probes initial implementation; Support x86/ARM/MIPS for both user and kernel spaces.
- * 2010 Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
- * 2012-2013 Vyacheslav Cherkashin <v.cherkashin@samsung.com> new memory allocator for slots
+ * @section DESCRIPTION
+ *
+ * SWAP slots interface declaration.
*/
+#ifndef _SWAP_SLOTS_H
+#define _SWAP_SLOTS_H
+
#include <linux/types.h>
+/**
+ * @struct slot_manager
+ * @brief Manage slots.
+ * @var slot_manager::slot_size
+ * Size of the slot.
+ * @var slot_manager::alloc
+ * Memory allocation callback.
+ * @var slot_manager::free
+ * Memory release callback.
+ * @var slot_manager::page_list
+ * List of pages.
+ * @var slot_manager::data
+ * Slot manager data. task_struct pointer usually stored here.
+ */
struct slot_manager {
unsigned long slot_size; /* FIXME: allocated in long (4 byte) */
void *(*alloc)(struct slot_manager *sm);