Add support for amd64/x86-64. Patch from Mike Frysinger.

Mon Aug  1 23:49:51 2005  Soeren Sandmann  <sandmann@redhat.com>

        * module/sysprof-module.c (REG_INS_PTR): Add support for
        amd64/x86-64. Patch from Mike Frysinger.
This commit is contained in:
Soeren Sandmann
2005-08-02 03:52:30 +00:00
committed by Søren Sandmann Pedersen
parent 775a1e3c5d
commit fbc7b471d2
2 changed files with 35 additions and 8 deletions

View File

@ -1,3 +1,8 @@
Mon Aug 1 23:49:51 2005 Soeren Sandmann <sandmann@redhat.com>
* module/sysprof-module.c (REG_INS_PTR): Add support for
amd64/x86-64. Patch from Mike Frysinger.
Sun Jul 10 10:51:52 2005 Soeren Sandmann <sandmann@redhat.com>
* binfile.c: Various minor clean-ups

View File

@ -20,6 +20,9 @@
*/
#include <linux/config.h>
#if !CONFIG_PROFILING
# error Sysprof needs a kernel with profiling support compiled in.
#endif
#ifdef CONFIG_SMP
# define __SMP__
#endif
@ -33,10 +36,14 @@
#include <linux/poll.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/profile.h>
#include "sysprof-module.h"
#include <linux/version.h>
#if KERNEL_VERSION(2,6,11) > LINUX_VERSION_CODE
# error Sysprof needs a Linux 2.6.11 kernel or later
#endif
#include <linux/kallsyms.h>
MODULE_LICENSE("GPL");
@ -52,6 +59,19 @@ static SysprofStackTrace * tail = &stack_traces[0];
DECLARE_WAIT_QUEUE_HEAD (wait_for_trace);
DECLARE_WAIT_QUEUE_HEAD (wait_for_exit);
/* Macro the names of the registers that are used on each architecture */
#if defined(CONFIG_X86_64)
# define REG_FRAME_PTR rbp
# define REG_INS_PTR rip
# define REG_STACK_PTR rsp
#elif defined(CONFIG_X86)
# define REG_FRAME_PTR ebp
# define REG_INS_PTR eip
# define REG_STACK_PTR esp
#else
# error Sysprof only supports the i386 and x86-64 architectures
#endif
#if 0
static void on_timer(unsigned long);
#endif
@ -306,21 +326,21 @@ generate_stack_trace(struct task_struct *task,
trace->pid = task->pid;
trace->truncated = 0;
trace->addresses[0] = (void *)regs->eip;
trace->addresses[0] = (void *)regs->REG_INS_PTR;
i = 1;
addr = regs->ebp;
addr = regs->REG_FRAME_PTR;
#if 0
printk (KERN_ALERT "ebp: %p\n", regs->ebp);
printk (KERN_ALERT "frame pointer: %p\n", regs->REG_FRAME_PTR);
#endif
if (init_userspace_reader (&reader, task))
{
while (i < SYSPROF_MAX_ADDRESSES &&
read_frame (&reader, addr, &frame) &&
addr < START_OF_STACK && addr >= regs->esp)
addr < START_OF_STACK && addr >= regs->REG_STACK_PTR)
{
trace->addresses[i++] = (void *)frame.return_address;
addr = frame.next;
@ -454,16 +474,16 @@ timer_notify (struct pt_regs *regs)
trace->pid = current->pid;
trace->truncated = 0;
trace->addresses[0] = (void *)regs->eip;
trace->addresses[0] = (void *)regs->REG_INS_PTR;
i = 1;
frame = (StackFrame *)regs->ebp;
frame = (StackFrame *)regs->REG_FRAME_PTR;
while (pages_present (frame) &&
i < SYSPROF_MAX_ADDRESSES &&
((unsigned long)frame) < START_OF_STACK &&
(unsigned long)frame >= regs->esp)
(unsigned long)frame >= regs->REG_STACK_PTR)
{
trace->addresses[i++] = (void *)frame->return_address;
frame = (StackFrame *)frame->next;
@ -540,7 +560,7 @@ init_module(void)
mod_timer(&timer, jiffies + INTERVAL);
#endif
printk(KERN_ALERT "starting sysprof module\n");
printk(KERN_ALERT "sysprof: loaded\n");
return 0;
}
@ -555,5 +575,7 @@ cleanup_module(void)
unregister_timer_hook (timer_notify);
remove_proc_entry("sysprof-trace", &proc_root);
printk(KERN_ALERT "sysprof: unloaded\n");
}