struct uretprobe_instance;
+static inline unsigned long swap_get_upc_arm(struct pt_regs *regs)
+{
+ return regs->ARM_pc | !!thumb_mode(regs);
+}
+
+static inline void swap_set_upc_arm(struct pt_regs *regs, unsigned long val)
+{
+ if (val & 1) {
+ regs->ARM_pc = val & ~1UL;
+ regs->ARM_cpsr |= PSR_T_BIT;
+ } else {
+ regs->ARM_pc = val;
+ regs->ARM_cpsr &= ~PSR_T_BIT;
+ }
+}
+
static inline unsigned long swap_get_uarg_arm(struct pt_regs *regs,
unsigned long n)
{
}
}
+static inline unsigned long swap_get_uret_addr_arm(struct pt_regs *regs)
+{
+ return regs->ARM_lr;
+}
+
+static inline void swap_set_uret_addr_arm(struct pt_regs *regs, unsigned long v)
+{
+ regs->ARM_lr = v;
+}
+
int arch_prepare_uprobe_arm(struct uprobe *p);
int arch_arm_uprobe_arm(struct uprobe *p);
void arch_disarm_uprobe_arm(struct uprobe *p, struct task_struct *task);
struct pd_t *pd = _get_process_data(ri->rp);
struct hd_t *hd;
unsigned long vaddr = 0;
- unsigned long old_pc = swap_get_instr_ptr(regs);
+ unsigned long old_pc = swap_get_upc(regs);
if ((dentry == NULL) || _is_in_handler())
goto out_set_orig;
loader_set_priv_origin(ri, vaddr);
/* PC change check */
- return old_pc != swap_get_instr_ptr(regs);
+ return old_pc != swap_get_upc(regs);
}
static int dl_fixup_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
* @param regs Pointer to CPU registers data.
* @return Pointer to pc.
*/
-static inline unsigned long swap_get_instr_ptr(struct pt_regs *regs)
+static inline unsigned long swap_get_kpc(struct pt_regs *regs)
{
return regs->ARM_pc | !!thumb_mode(regs);
}
* @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)
+static inline void swap_set_kpc(struct pt_regs *regs, unsigned long val)
{
if (val & 1) {
regs->ARM_pc = val & ~1;
}
/**
- * @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.
return swap_get_karg(regs, n);
}
-static inline unsigned long swap_get_instr_ptr(struct pt_regs *regs)
+static inline unsigned long swap_get_kpc(struct pt_regs *regs)
{
WARN(1, "not implemented"); /* FIXME: to implement */
return 0xdeadc0de;
}
-static inline void swap_set_instr_ptr(struct pt_regs *regs, unsigned long val)
-{
- WARN(1, "not implemented"); /* FIXME: to implement */
-}
-
-static inline unsigned long swap_get_ret_addr(struct pt_regs *regs)
-{
- WARN(1, "not implemented"); /* FIXME: to implement */
- return 0xdeadc0de;
-}
-
-static inline void swap_set_ret_addr(struct pt_regs *regs, unsigned long val)
+static inline void swap_set_kpc(struct pt_regs *regs, unsigned long val)
{
WARN(1, "not implemented"); /* FIXME: to implement */
}
regs->EREG(sp) = sp;
}
-static inline unsigned long swap_get_instr_ptr(struct pt_regs *regs)
+static inline unsigned long swap_get_kpc(struct pt_regs *regs)
{
- return regs->EREG(ip);
+ return regs->ip;
}
-static inline void swap_set_instr_ptr(struct pt_regs *regs, unsigned long val)
+static inline void swap_set_kpc(struct pt_regs *regs, unsigned long val)
{
- regs->EREG(ip) = val;
-}
-
-static inline unsigned long swap_get_ret_addr(struct pt_regs *regs)
-{
- unsigned long addr = 0;
- read_proc_vm_atomic(current, regs->EREG(sp), &addr, sizeof(addr));
- return addr;
-}
-
-static inline void swap_set_ret_addr(struct pt_regs *regs, unsigned long val)
-{
- write_proc_vm_atomic(current, regs->EREG(sp), &val, sizeof(val));
+ regs->ip = val;
}
static inline unsigned long swap_get_arg(struct pt_regs *regs, int num)
&val, sizeof(val));
}
-static inline int swap_fp_backtrace(struct task_struct *task,
- unsigned long *buf, int max_cnt)
-{
- int i = 0;
- struct pt_regs *regs;
-
- struct {
- unsigned long next;
- unsigned long raddr;
- } frame;
-
-
- regs = task_pt_regs(task);
- frame.next = regs->EREG(bp);
- frame.raddr = swap_get_ret_addr(regs);
-
- while (frame.next && i < max_cnt) {
- if (read_proc_vm_atomic(task, frame.next, &frame, sizeof(frame))
- == sizeof(frame))
- buf[i++] = frame.raddr;
- else
- break;
- }
-
- return i;
-}
-
/**
* @struct prev_kp_core
* @brief Stores previous kp_core.
ri->preload.thumb = !!thumb_mode(regs);
#endif /* CONFIG_ARM */
- swap_set_instr_ptr(regs, vaddr);
+ swap_set_upc(regs, vaddr);
}
static inline void __save_uregs(struct uretprobe_instance *ri,
memcpy(ri->data, regs, sizeof(*regs));
priv->arg0 = swap_get_uarg(regs, 0);
priv->arg1 = swap_get_uarg(regs, 1);
- priv->raddr = swap_get_ret_addr(regs);
+ priv->raddr = swap_get_uret_addr(regs);
}
static inline void __restore_uregs(struct uretprobe_instance *ri,
memcpy(regs, ri->data, sizeof(*regs));
swap_put_uarg(regs, 0, priv->arg0);
swap_put_uarg(regs, 1, priv->arg1);
- swap_set_ret_addr(regs, priv->raddr);
+ swap_set_uret_addr(regs, priv->raddr);
#ifdef CONFIG_X86_32
/* need to do it only on x86 */
regs->EREG(ip) -= 1;
(int)lpd_get_state(hd),
prefix, (unsigned long)ri->rp->up.addr,
regs->EREG(ip), swap_get_uarg(regs, 0), swap_get_uarg(regs, 1),
- swap_get_ret_addr(regs));
+ swap_get_uret_addr(regs));
#elif defined(CONFIG_ARM64)
WARN(1, "not implemented"); /* FIXME: to implement */
(void)dentry;
{
struct pd_t *pd = __get_process_data(ri->rp);
struct hd_t *hd;
- unsigned long old_pc = swap_get_instr_ptr(regs);
+ unsigned long old_pc = swap_get_upc(regs);
unsigned long flags = pt_get_flags(current);
struct sspt_ip *ip = container_of(ri->rp, struct sspt_ip, retprobe);
unsigned long vaddr = 0;
loader_set_priv_origin(ri, vaddr);
/* PC change check */
- return old_pc != swap_get_instr_ptr(regs);
+ return old_pc != swap_get_upc(regs);
}
static void __do_preload_ret(struct uretprobe_instance *ri, struct hd_t *hd)
{
struct pd_t *pd = __get_process_data(ri->rp);
struct hd_t *hd;
- unsigned long old_pc = swap_get_instr_ptr(regs);
+ unsigned long old_pc = swap_get_upc(regs);
unsigned long vaddr = 0;
if (uihv_dentry == NULL)
loader_set_priv_origin(ri, vaddr);
/* PC change check */
- return old_pc != swap_get_instr_ptr(regs);
+ return old_pc != swap_get_upc(regs);
}
static int uihv_main_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
struct task_struct *task)
{
struct pt_regs *uregs = task_pt_regs(ri->task);
- unsigned long ra = swap_get_ret_addr(uregs);
+ unsigned long ra = uregs->ARM_lr;
unsigned long *tramp = (unsigned long *)arch_tramp_by_ri(ri);
unsigned long *sp = (unsigned long *)((long)ri->sp & ~1);
unsigned long *stack = sp - RETPROBE_STACK_DEPTH + 1;
"lr = %08lx - %lx, set ret_addr=%p\n",
task->comm, task->tgid, task->pid, ra, vaddr, ri->ret_addr);
- swap_set_ret_addr(uregs, (unsigned long)ri->ret_addr);
+ swap_set_uret_addr(uregs, (unsigned long)ri->ret_addr);
retval = 0;
} else if (retval) {
printk(KERN_INFO "---> %s (%d/%d): trampoline NOT found at "
arch_disarm_uprobe_arm(p, task);
}
+static inline unsigned long swap_get_upc(struct pt_regs *regs)
+{
+ return swap_get_upc_arm(regs);
+}
+
+static inline void swap_set_upc(struct pt_regs *regs, unsigned long val)
+{
+ swap_set_upc_arm(regs, val);
+}
+
static inline unsigned long swap_get_uarg(struct pt_regs *regs, unsigned long n)
{
return swap_get_uarg_arm(regs, n);
swap_put_uarg_arm(regs, n, val);
}
+static inline unsigned long swap_get_uret_addr(struct pt_regs *regs)
+{
+ return swap_get_uret_addr_arm(regs);
+}
+
+static inline void swap_set_uret_addr(struct pt_regs *regs, unsigned long val)
+{
+ swap_set_uret_addr_arm(regs, val);
+}
+
int swap_arch_init_uprobes(void);
void swap_arch_exit_uprobes(void);
}
}
+static inline unsigned long swap_get_upc(struct pt_regs *regs)
+{
+ WARN(1, "not implemented"); /* FIXME: to implement */
+ return 0;
+}
+
+static inline void swap_set_upc(struct pt_regs *regs, unsigned long val)
+{
+ WARN(1, "not implemented"); /* FIXME: to implement */
+}
+
static inline unsigned long swap_get_uarg(struct pt_regs *regs, unsigned long n)
{
if (compat_user_mode(regs))
WARN(1, "not implemented"); /* FIXME: to implement */
}
+static inline unsigned long swap_get_uret_addr(struct pt_regs *regs)
+{
+ WARN(1, "not implemented"); /* FIXME: to implement */
+ return 0;
+}
+
+static inline void swap_set_uret_addr(struct pt_regs *regs, unsigned long val)
+{
+ WARN(1, "not implemented"); /* FIXME: to implement */
+}
+
int arch_prepare_uprobe(struct uprobe *p);
void arch_remove_uprobe(struct uprobe *p);
int arch_arm_uprobe(struct uprobe *p);
void arch_disarm_uprobe(struct uprobe *p, struct task_struct *task);
-static inline unsigned long swap_get_uarg(struct pt_regs *regs, unsigned long n)
+static inline unsigned long swap_get_upc(struct pt_regs *regs)
+{
+ return regs->ip;
+}
+
+static inline void swap_set_upc(struct pt_regs *regs, unsigned long val)
+{
+ regs->ip = val;
+}
+
+static inline unsigned long swap_get_ustack_val(struct pt_regs *regs,
+ unsigned long n)
{
u32 *ptr, addr = 0;
- /* 1 - return address saved on top of the stack */
- ptr = (u32 *)regs->sp + n + 1;
+ ptr = (u32 *)regs->sp + n;
if (get_user(addr, ptr))
- printk(KERN_INFO "failed to dereference a pointer, ptr=%p\n",
- ptr);
+ pr_err("Failed to dereference a pointer, ptr=%p\n", ptr);
return addr;
}
-static inline void swap_put_uarg(struct pt_regs *regs, unsigned long n,
- unsigned long val)
+static inline void swap_set_ustack_val(struct pt_regs *regs, unsigned long n,
+ unsigned long val)
{
u32 *ptr;
- /* 1 - return address saved on top of the stack */
- ptr = (u32 *)regs->sp + n + 1;
+ ptr = (u32 *)regs->sp + n;
if (put_user(val, ptr))
- printk(KERN_INFO "failed to dereference a pointer, ptr=%p\n",
- ptr);
+ pr_err("Failed to dereference a pointer, ptr=%p\n", ptr);
}
+static inline unsigned long swap_get_uarg(struct pt_regs *regs, unsigned long n)
+{
+ /* 1 - return address saved on top of the stack */
+ return swap_get_ustack_val(regs, n + 1);
+}
+
+static inline void swap_put_uarg(struct pt_regs *regs, unsigned long n,
+ unsigned long val)
+{
+ /* 1 - return address saved on top of the stack */
+ swap_set_ustack_val(regs, n + 1, val);
+}
+
+static inline unsigned long swap_get_uret_addr(struct pt_regs *regs)
+{
+ return swap_get_ustack_val(regs, 0);
+}
+
+static inline void swap_set_uret_addr(struct pt_regs *regs, unsigned long val)
+{
+ swap_set_ustack_val(regs, 0, val);
+}
+
+
int swap_arch_init_uprobes(void);
void swap_arch_exit_uprobes(void);