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
tools
perf
util
vdso.c
Go to the documentation of this file.
1
2
#include <unistd.h>
3
#include <
stdio.h
>
4
#include <string.h>
5
#include <sys/types.h>
6
#include <sys/stat.h>
7
#include <fcntl.h>
8
#include <
stdlib.h
>
9
#include <linux/kernel.h>
10
11
#include "
vdso.h
"
12
#include "
util.h
"
13
#include "
symbol.h
"
14
#include "linux/string.h"
15
16
static
bool
vdso_found;
17
static
char
vdso_file[] =
"/tmp/perf-vdso.so-XXXXXX"
;
18
19
static
int
find_vdso_map(
void
**
start
,
void
**
end
)
20
{
21
FILE *maps;
22
char
line
[128];
23
int
found = 0;
24
25
maps = fopen(
"/proc/self/maps"
,
"r"
);
26
if
(!maps) {
27
pr_err
(
"vdso: cannot open maps\n"
);
28
return
-1;
29
}
30
31
while
(!found && fgets(line,
sizeof
(line), maps)) {
32
int
m
= -1;
33
34
/* We care only about private r-x mappings. */
35
if
(2 !=
sscanf
(line,
"%p-%p r-xp %*x %*x:%*x %*u %n"
,
36
start, end, &m))
37
continue
;
38
if
(m < 0)
39
continue
;
40
41
if
(!
strncmp
(&line[m],
VDSO__MAP_NAME
,
42
sizeof
(
VDSO__MAP_NAME
) - 1))
43
found = 1;
44
}
45
46
fclose(maps);
47
return
!found;
48
}
49
50
static
char
*get_file(
void
)
51
{
52
char
*vdso =
NULL
;
53
char
*
buf
=
NULL
;
54
void
*
start
, *
end
;
55
size_t
size
;
56
int
fd
;
57
58
if
(vdso_found)
59
return
vdso_file;
60
61
if
(find_vdso_map(&start, &end))
62
return
NULL
;
63
64
size = end -
start
;
65
66
buf =
memdup
(start, size);
67
if
(!buf)
68
return
NULL
;
69
70
fd = mkstemp(vdso_file);
71
if
(fd < 0)
72
goto
out
;
73
74
if
(size == (
size_t
)
write
(fd, buf, size))
75
vdso = vdso_file;
76
77
close(fd);
78
79
out
:
80
free
(buf);
81
82
vdso_found = (vdso !=
NULL
);
83
return
vdso;
84
}
85
86
void
vdso__exit
(
void
)
87
{
88
if
(vdso_found)
89
unlink(vdso_file);
90
}
91
92
struct
dso
*
vdso__dso_findnew
(
struct
list_head
*
head
)
93
{
94
struct
dso
*
dso
=
dsos__find
(head,
VDSO__MAP_NAME
);
95
96
if
(!dso) {
97
char
*
file
;
98
99
file = get_file();
100
if
(!file)
101
return
NULL
;
102
103
dso =
dso__new
(
VDSO__MAP_NAME
);
104
if
(dso !=
NULL
) {
105
dsos__add
(head, dso);
106
dso__set_long_name
(dso, file);
107
}
108
}
109
110
return
dso;
111
}
Generated on Thu Jan 10 2013 13:03:45 for Linux Kernel by
1.8.2