Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
avr32
oprofile
backtrace.c
Go to the documentation of this file.
1
/*
2
* AVR32 specific backtracing code for oprofile
3
*
4
* Copyright 2008 Weinmann GmbH
5
*
6
* Author: Nikolaus Voss <
[email protected]
>
7
*
8
* Based on i386 oprofile backtrace code by John Levon and David Smith
9
*
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License version 2 as
12
* published by the Free Software Foundation.
13
*
14
*/
15
16
#include <
linux/oprofile.h
>
17
#include <linux/sched.h>
18
#include <
linux/uaccess.h
>
19
20
/* The first two words of each frame on the stack look like this if we have
21
* frame pointers */
22
struct
frame_head
{
23
unsigned
long
lr
;
24
struct
frame_head
*
fp
;
25
};
26
27
/* copied from arch/avr32/kernel/process.c */
28
static
inline
int
valid_stack_ptr(
struct
thread_info
*
tinfo
,
unsigned
long
p
)
29
{
30
return
(p > (
unsigned
long
)tinfo)
31
&& (p < (
unsigned
long
)tinfo +
THREAD_SIZE
- 3);
32
}
33
34
/* copied from arch/x86/oprofile/backtrace.c */
35
static
struct
frame_head
*dump_user_backtrace(
struct
frame_head
*
head
)
36
{
37
struct
frame_head
bufhead[2];
38
39
/* Also check accessibility of one struct frame_head beyond */
40
if
(!
access_ok
(
VERIFY_READ
, head,
sizeof
(bufhead)))
41
return
NULL
;
42
if
(
__copy_from_user_inatomic
(bufhead, head,
sizeof
(bufhead)))
43
return
NULL
;
44
45
oprofile_add_trace
(bufhead[0].
lr
);
46
47
/* frame pointers should strictly progress back up the stack
48
* (towards higher addresses) */
49
if
(bufhead[0].
fp
<= head)
50
return
NULL
;
51
52
return
bufhead[0].fp;
53
}
54
55
void
avr32_backtrace
(
struct
pt_regs
*
const
regs
,
unsigned
int
depth
)
56
{
57
/* Get first frame pointer */
58
struct
frame_head
*head = (
struct
frame_head
*)(regs->
r7
);
59
60
if
(!
user_mode
(regs)) {
61
#ifdef CONFIG_FRAME_POINTER
62
/*
63
* Traverse the kernel stack from frame to frame up to
64
* "depth" steps.
65
*/
66
while
(depth-- && valid_stack_ptr(
task_thread_info
(
current
),
67
(
unsigned
long
)head)) {
68
oprofile_add_trace
(head->lr);
69
if
(head->fp <= head)
70
break
;
71
head = head->fp;
72
}
73
#endif
74
}
else
{
75
/* Assume we have frame pointers in user mode process */
76
while
(depth-- && head)
77
head = dump_user_backtrace(head);
78
}
79
}
80
81
Generated on Thu Jan 10 2013 13:04:03 for Linux Kernel by
1.8.2