aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/Makefile1
-rw-r--r--tools/perf/builtin-annotate.c79
-rw-r--r--tools/perf/builtin-record.c1
-rw-r--r--tools/perf/builtin-report.c124
-rw-r--r--tools/perf/util/callchain.h1
-rw-r--r--tools/perf/util/event.h30
-rw-r--r--tools/perf/util/map.c97
-rw-r--r--tools/perf/util/symbol.h1
-rw-r--r--tools/perf/util/util.h1
9 files changed, 137 insertions, 198 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 2aee21baf785..cb9033d3f72f 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -340,6 +340,7 @@ LIB_OBJS += util/header.o
340LIB_OBJS += util/callchain.o 340LIB_OBJS += util/callchain.o
341LIB_OBJS += util/values.o 341LIB_OBJS += util/values.o
342LIB_OBJS += util/debug.o 342LIB_OBJS += util/debug.o
343LIB_OBJS += util/map.o
343 344
344BUILTIN_OBJS += builtin-annotate.o 345BUILTIN_OBJS += builtin-annotate.o
345BUILTIN_OBJS += builtin-help.o 346BUILTIN_OBJS += builtin-help.o
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index fee663adeea2..543c4524f8c2 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -51,83 +51,6 @@ struct sym_ext {
51 char *path; 51 char *path;
52}; 52};
53 53
54struct map {
55 struct list_head node;
56 u64 start;
57 u64 end;
58 u64 pgoff;
59 u64 (*map_ip)(struct map *, u64);
60 struct dso *dso;
61};
62
63static u64 map__map_ip(struct map *map, u64 ip)
64{
65 return ip - map->start + map->pgoff;
66}
67
68static u64 vdso__map_ip(struct map *map __used, u64 ip)
69{
70 return ip;
71}
72
73static struct map *map__new(struct mmap_event *event)
74{
75 struct map *self = malloc(sizeof(*self));
76
77 if (self != NULL) {
78 const char *filename = event->filename;
79
80 self->start = event->start;
81 self->end = event->start + event->len;
82 self->pgoff = event->pgoff;
83
84 self->dso = dsos__findnew(filename);
85 if (self->dso == NULL)
86 goto out_delete;
87
88 if (self->dso == vdso)
89 self->map_ip = vdso__map_ip;
90 else
91 self->map_ip = map__map_ip;
92 }
93 return self;
94out_delete:
95 free(self);
96 return NULL;
97}
98
99static struct map *map__clone(struct map *self)
100{
101 struct map *map = malloc(sizeof(*self));
102
103 if (!map)
104 return NULL;
105
106 memcpy(map, self, sizeof(*self));
107
108 return map;
109}
110
111static int map__overlap(struct map *l, struct map *r)
112{
113 if (l->start > r->start) {
114 struct map *t = l;
115 l = r;
116 r = t;
117 }
118
119 if (l->end > r->start)
120 return 1;
121
122 return 0;
123}
124
125static size_t map__fprintf(struct map *self, FILE *fp)
126{
127 return fprintf(fp, " %Lx-%Lx %Lx %s\n",
128 self->start, self->end, self->pgoff, self->dso->name);
129}
130
131 54
132struct thread { 55struct thread {
133 struct rb_node rb_node; 56 struct rb_node rb_node;
@@ -797,7 +720,7 @@ static int
797process_mmap_event(event_t *event, unsigned long offset, unsigned long head) 720process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
798{ 721{
799 struct thread *thread = threads__findnew(event->mmap.pid); 722 struct thread *thread = threads__findnew(event->mmap.pid);
800 struct map *map = map__new(&event->mmap); 723 struct map *map = map__new(&event->mmap, NULL, 0);
801 724
802 dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n", 725 dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
803 (void *)(offset + head), 726 (void *)(offset + head),
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 718b8f7b6aac..106c6abd1c38 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -15,6 +15,7 @@
15#include "util/string.h" 15#include "util/string.h"
16 16
17#include "util/header.h" 17#include "util/header.h"
18#include "util/event.h"
18 19
19#include <unistd.h> 20#include <unistd.h>
20#include <sched.h> 21#include <sched.h>
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 1efefcc2ffdf..93945ecdac86 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -67,6 +67,10 @@ static char callchain_default_opt[] = "fractal,0.5";
67 67
68static int callchain; 68static int callchain;
69 69
70static char __cwd[PATH_MAX];
71static char *cwd = __cwd;
72static int cwdlen;
73
70static 74static
71struct callchain_param callchain_param = { 75struct callchain_param callchain_param = {
72 .mode = CHAIN_GRAPH_REL, 76 .mode = CHAIN_GRAPH_REL,
@@ -102,124 +106,6 @@ static int repsep_fprintf(FILE *fp, const char *fmt, ...)
102 return n; 106 return n;
103} 107}
104 108
105
106
107static char __cwd[PATH_MAX];
108static char *cwd = __cwd;
109static int cwdlen;
110
111static int strcommon(const char *pathname)
112{
113 int n = 0;
114
115 while (n < cwdlen && pathname[n] == cwd[n])
116 ++n;
117
118 return n;
119}
120
121struct map {
122 struct list_head node;
123 u64 start;
124 u64 end;
125 u64 pgoff;
126 u64 (*map_ip)(struct map *, u64);
127 struct dso *dso;
128};
129
130static u64 map__map_ip(struct map *map, u64 ip)
131{
132 return ip - map->start + map->pgoff;
133}
134
135static u64 vdso__map_ip(struct map *map __used, u64 ip)
136{
137 return ip;
138}
139
140static inline int is_anon_memory(const char *filename)
141{
142 return strcmp(filename, "//anon") == 0;
143}
144
145static struct map *map__new(struct mmap_event *event)
146{
147 struct map *self = malloc(sizeof(*self));
148
149 if (self != NULL) {
150 const char *filename = event->filename;
151 char newfilename[PATH_MAX];
152 int anon;
153
154 if (cwd) {
155 int n = strcommon(filename);
156
157 if (n == cwdlen) {
158 snprintf(newfilename, sizeof(newfilename),
159 ".%s", filename + n);
160 filename = newfilename;
161 }
162 }
163
164 anon = is_anon_memory(filename);
165
166 if (anon) {
167 snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
168 filename = newfilename;
169 }
170
171 self->start = event->start;
172 self->end = event->start + event->len;
173 self->pgoff = event->pgoff;
174
175 self->dso = dsos__findnew(filename);
176 if (self->dso == NULL)
177 goto out_delete;
178
179 if (self->dso == vdso || anon)
180 self->map_ip = vdso__map_ip;
181 else
182 self->map_ip = map__map_ip;
183 }
184 return self;
185out_delete:
186 free(self);
187 return NULL;
188}
189
190static struct map *map__clone(struct map *self)
191{
192 struct map *map = malloc(sizeof(*self));
193
194 if (!map)
195 return NULL;
196
197 memcpy(map, self, sizeof(*self));
198
199 return map;
200}
201
202static int map__overlap(struct map *l, struct map *r)
203{
204 if (l->start > r->start) {
205 struct map *t = l;
206 l = r;
207 r = t;
208 }
209
210 if (l->end > r->start)
211 return 1;
212
213 return 0;
214}
215
216static size_t map__fprintf(struct map *self, FILE *fp)
217{
218 return fprintf(fp, " %Lx-%Lx %Lx %s\n",
219 self->start, self->end, self->pgoff, self->dso->name);
220}
221
222
223struct thread { 109struct thread {
224 struct rb_node rb_node; 110 struct rb_node rb_node;
225 struct list_head maps; 111 struct list_head maps;
@@ -1474,7 +1360,7 @@ static int
1474process_mmap_event(event_t *event, unsigned long offset, unsigned long head) 1360process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
1475{ 1361{
1476 struct thread *thread = threads__findnew(event->mmap.pid); 1362 struct thread *thread = threads__findnew(event->mmap.pid);
1477 struct map *map = map__new(&event->mmap); 1363 struct map *map = map__new(&event->mmap, cwd, cwdlen);
1478 1364
1479 dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n", 1365 dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
1480 (void *)(offset + head), 1366 (void *)(offset + head),
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index a926ae4f5a16..43cf3ea9e088 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -4,6 +4,7 @@
4#include "../perf.h" 4#include "../perf.h"
5#include <linux/list.h> 5#include <linux/list.h>
6#include <linux/rbtree.h> 6#include <linux/rbtree.h>
7#include "util.h"
7#include "symbol.h" 8#include "symbol.h"
8 9
9enum chain_mode { 10enum chain_mode {
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 91e2fe589f27..d26dc887ce52 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -1,4 +1,8 @@
1#ifndef __PERF_EVENT_H
2#define __PERF_EVENT_H
1#include "../perf.h" 3#include "../perf.h"
4#include "util.h"
5#include <linux/list.h>
2 6
3struct ip_event { 7struct ip_event {
4 struct perf_event_header header; 8 struct perf_event_header header;
@@ -52,3 +56,29 @@ typedef union event_union {
52 struct lost_event lost; 56 struct lost_event lost;
53 struct read_event read; 57 struct read_event read;
54} event_t; 58} event_t;
59
60struct map {
61 struct list_head node;
62 u64 start;
63 u64 end;
64 u64 pgoff;
65 u64 (*map_ip)(struct map *, u64);
66 struct dso *dso;
67};
68
69static inline u64 map__map_ip(struct map *map, u64 ip)
70{
71 return ip - map->start + map->pgoff;
72}
73
74static inline u64 vdso__map_ip(struct map *map __used, u64 ip)
75{
76 return ip;
77}
78
79struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen);
80struct map *map__clone(struct map *self);
81int map__overlap(struct map *l, struct map *r);
82size_t map__fprintf(struct map *self, FILE *fp);
83
84#endif
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
new file mode 100644
index 000000000000..804e02382739
--- /dev/null
+++ b/tools/perf/util/map.c
@@ -0,0 +1,97 @@
1#include "event.h"
2#include "symbol.h"
3#include <stdlib.h>
4#include <string.h>
5#include <stdio.h>
6
7static inline int is_anon_memory(const char *filename)
8{
9 return strcmp(filename, "//anon") == 0;
10}
11
12static int strcommon(const char *pathname, char *cwd, int cwdlen)
13{
14 int n = 0;
15
16 while (n < cwdlen && pathname[n] == cwd[n])
17 ++n;
18
19 return n;
20}
21
22 struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen)
23{
24 struct map *self = malloc(sizeof(*self));
25
26 if (self != NULL) {
27 const char *filename = event->filename;
28 char newfilename[PATH_MAX];
29 int anon;
30
31 if (cwd) {
32 int n = strcommon(filename, cwd, cwdlen);
33
34 if (n == cwdlen) {
35 snprintf(newfilename, sizeof(newfilename),
36 ".%s", filename + n);
37 filename = newfilename;
38 }
39 }
40
41 anon = is_anon_memory(filename);
42
43 if (anon) {
44 snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
45 filename = newfilename;
46 }
47
48 self->start = event->start;
49 self->end = event->start + event->len;
50 self->pgoff = event->pgoff;
51
52 self->dso = dsos__findnew(filename);
53 if (self->dso == NULL)
54 goto out_delete;
55
56 if (self->dso == vdso || anon)
57 self->map_ip = vdso__map_ip;
58 else
59 self->map_ip = map__map_ip;
60 }
61 return self;
62out_delete:
63 free(self);
64 return NULL;
65}
66
67struct map *map__clone(struct map *self)
68{
69 struct map *map = malloc(sizeof(*self));
70
71 if (!map)
72 return NULL;
73
74 memcpy(map, self, sizeof(*self));
75
76 return map;
77}
78
79int map__overlap(struct map *l, struct map *r)
80{
81 if (l->start > r->start) {
82 struct map *t = l;
83 l = r;
84 r = t;
85 }
86
87 if (l->end > r->start)
88 return 1;
89
90 return 0;
91}
92
93size_t map__fprintf(struct map *self, FILE *fp)
94{
95 return fprintf(fp, " %Lx-%Lx %Lx %s\n",
96 self->start, self->end, self->pgoff, self->dso->name);
97}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index f3490fcd40ee..50f723571241 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -6,6 +6,7 @@
6#include <linux/list.h> 6#include <linux/list.h>
7#include <linux/rbtree.h> 7#include <linux/rbtree.h>
8#include "module.h" 8#include "module.h"
9#include "event.h"
9 10
10struct symbol { 11struct symbol {
11 struct rb_node rb_node; 12 struct rb_node rb_node;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index be4b52cca2c3..d61a6f037631 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -83,7 +83,6 @@
83#include <inttypes.h> 83#include <inttypes.h>
84#include "../../../include/linux/magic.h" 84#include "../../../include/linux/magic.h"
85 85
86#include "event.h"
87 86
88#ifndef NO_ICONV 87#ifndef NO_ICONV
89#include <iconv.h> 88#include <iconv.h>