summaryrefslogtreecommitdiffstats
path: root/runtime/unwind/i386.h
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2008-03-25 11:46:14 -0400
committerFrank Ch. Eigler <fche@elastic.org>2008-03-25 11:46:14 -0400
commit949e84da2d80837b192209efb4122f2ff59ab54d (patch)
tree3b09669cc429da4218f8ca3157bc78133ea1b0ab /runtime/unwind/i386.h
parent6043234f6d6efba366f67666b2197a47f5bdafce (diff)
downloadsystemtap-steved-949e84da2d80837b192209efb4122f2ff59ab54d.tar.gz
systemtap-steved-949e84da2d80837b192209efb4122f2ff59ab54d.tar.xz
systemtap-steved-949e84da2d80837b192209efb4122f2ff59ab54d.zip
add (back) runtime/unwind files
Diffstat (limited to 'runtime/unwind/i386.h')
-rw-r--r--runtime/unwind/i386.h97
1 files changed, 97 insertions, 0 deletions
diff --git a/runtime/unwind/i386.h b/runtime/unwind/i386.h
new file mode 100644
index 00000000..de68c67b
--- /dev/null
+++ b/runtime/unwind/i386.h
@@ -0,0 +1,97 @@
+#ifndef _STP_I386_UNWIND_H
+#define _STP_I386_UNWIND_H
+
+/*
+ * Copyright (C) 2002-2006 Novell, Inc.
+ * Jan Beulich <jbeulich@novell.com>
+ * This code is released under version 2 of the GNU GPL.
+ */
+
+
+#include <linux/sched.h>
+#include <asm/fixmap.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+/* these are simple for i386 */
+#define _stp_get_unaligned(ptr) (*(ptr))
+#define _stp_put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
+
+struct unwind_frame_info
+{
+ struct pt_regs regs;
+ struct task_struct *task;
+ unsigned call_frame:1;
+};
+
+#define UNW_PC(frame) (frame)->regs.eip
+#define UNW_SP(frame) (frame)->regs.esp
+#ifdef CONFIG_FRAME_POINTER
+#define UNW_FP(frame) (frame)->regs.ebp
+#define FRAME_RETADDR_OFFSET 4
+#define FRAME_LINK_OFFSET 0
+#define STACK_BOTTOM(tsk) STACK_LIMIT((tsk)->thread.esp0)
+#define STACK_TOP(tsk) ((tsk)->thread.esp0)
+#else
+#define UNW_FP(frame) ((void)(frame), 0)
+#endif
+#define STACK_LIMIT(ptr) (((ptr) - 1) & ~(THREAD_SIZE - 1))
+
+#define UNW_REGISTER_INFO \
+ PTREGS_INFO(eax), \
+ PTREGS_INFO(ecx), \
+ PTREGS_INFO(edx), \
+ PTREGS_INFO(ebx), \
+ PTREGS_INFO(esp), \
+ PTREGS_INFO(ebp), \
+ PTREGS_INFO(esi), \
+ PTREGS_INFO(edi), \
+ PTREGS_INFO(eip)
+
+#define UNW_DEFAULT_RA(raItem, dataAlign) \
+ ((raItem).where == Memory && \
+ !((raItem).value * (dataAlign) + 4))
+
+static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
+ /*const*/ struct pt_regs *regs)
+{
+ if (user_mode_vm(regs))
+ info->regs = *regs;
+ else {
+ memcpy(&info->regs, regs, offsetof(struct pt_regs, esp));
+ info->regs.esp = (unsigned long)&regs->esp;
+ info->regs.xss = __KERNEL_DS;
+ }
+}
+
+static inline void arch_unw_init_blocked(struct unwind_frame_info *info)
+{
+ memset(&info->regs, 0, sizeof(info->regs));
+ info->regs.eip = info->task->thread.eip;
+ info->regs.xcs = __KERNEL_CS;
+ __get_user(info->regs.ebp, (long *)info->task->thread.esp);
+ info->regs.esp = info->task->thread.esp;
+ info->regs.xss = __KERNEL_DS;
+ info->regs.xds = __USER_DS;
+ info->regs.xes = __USER_DS;
+}
+
+extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *,
+ asmlinkage int (*callback)(struct unwind_frame_info *,
+ void *arg),
+ void *arg);
+
+static inline int arch_unw_user_mode(const struct unwind_frame_info *info)
+{
+#if 0 /* This can only work when selector register and EFLAGS saves/restores
+ are properly annotated (and tracked in UNW_REGISTER_INFO). */
+ return user_mode_vm(&info->regs);
+#else
+ return info->regs.eip < PAGE_OFFSET
+ || (info->regs.eip >= __fix_to_virt(FIX_VDSO)
+ && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE)
+ || info->regs.esp < PAGE_OFFSET;
+#endif
+}
+
+#endif /* _STP_I386_UNWIND_H */