aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-record.c37
-rw-r--r--tools/perf/util/header.c7
-rw-r--r--tools/perf/util/session.c64
-rw-r--r--tools/perf/util/session.h3
-rw-r--r--tools/perf/util/symbol.c13
-rw-r--r--tools/perf/util/symbol.h2
6 files changed, 73 insertions, 53 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 949167efa1ed..706f00196b87 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -12,6 +12,7 @@
12 12
13#include "perf.h" 13#include "perf.h"
14 14
15#include "util/build-id.h"
15#include "util/util.h" 16#include "util/util.h"
16#include "util/parse-options.h" 17#include "util/parse-options.h"
17#include "util/parse-events.h" 18#include "util/parse-events.h"
@@ -65,6 +66,7 @@ static int nr_poll = 0;
65static int nr_cpu = 0; 66static int nr_cpu = 0;
66 67
67static int file_new = 1; 68static int file_new = 1;
69static off_t post_processing_offset;
68 70
69static struct perf_session *session; 71static struct perf_session *session;
70 72
@@ -114,26 +116,10 @@ static void write_output(void *buf, size_t size)
114 } 116 }
115} 117}
116 118
117static void write_event(event_t *buf, size_t size)
118{
119 /*
120 * Add it to the list of DSOs, so that when we finish this
121 * record session we can pick the available build-ids.
122 */
123 if (buf->header.type == PERF_RECORD_MMAP) {
124 struct list_head *head = &dsos__user;
125 if (buf->mmap.header.misc == 1)
126 head = &dsos__kernel;
127 __dsos__findnew(head, buf->mmap.filename);
128 }
129
130 write_output(buf, size);
131}
132
133static int process_synthesized_event(event_t *event, 119static int process_synthesized_event(event_t *event,
134 struct perf_session *self __used) 120 struct perf_session *self __used)
135{ 121{
136 write_event(event, event->header.size); 122 write_output(event, event->header.size);
137 return 0; 123 return 0;
138} 124}
139 125
@@ -185,14 +171,14 @@ static void mmap_read(struct mmap_data *md)
185 size = md->mask + 1 - (old & md->mask); 171 size = md->mask + 1 - (old & md->mask);
186 old += size; 172 old += size;
187 173
188 write_event(buf, size); 174 write_output(buf, size);
189 } 175 }
190 176
191 buf = &data[old & md->mask]; 177 buf = &data[old & md->mask];
192 size = head - old; 178 size = head - old;
193 old += size; 179 old += size;
194 180
195 write_event(buf, size); 181 write_output(buf, size);
196 182
197 md->prev = old; 183 md->prev = old;
198 mmap_write_tail(md, old); 184 mmap_write_tail(md, old);
@@ -402,10 +388,21 @@ static void open_counters(int cpu, pid_t pid)
402 nr_cpu++; 388 nr_cpu++;
403} 389}
404 390
391static int process_buildids(void)
392{
393 u64 size = lseek(output, 0, SEEK_CUR);
394
395 session->fd = output;
396 return __perf_session__process_events(session, post_processing_offset,
397 size - post_processing_offset,
398 size, &build_id__mark_dso_hit_ops);
399}
400
405static void atexit_header(void) 401static void atexit_header(void)
406{ 402{
407 session->header.data_size += bytes_written; 403 session->header.data_size += bytes_written;
408 404
405 process_buildids();
409 perf_header__write(&session->header, output, true); 406 perf_header__write(&session->header, output, true);
410} 407}
411 408
@@ -558,6 +555,8 @@ static int __cmd_record(int argc, const char **argv)
558 return err; 555 return err;
559 } 556 }
560 557
558 post_processing_offset = lseek(output, 0, SEEK_CUR);
559
561 err = event__synthesize_kernel_mmap(process_synthesized_event, 560 err = event__synthesize_kernel_mmap(process_synthesized_event,
562 session, "_text"); 561 session, "_text");
563 if (err < 0) { 562 if (err < 0) {
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ed3efd728b41..d5facd5ab1f7 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -205,8 +205,11 @@ static int __dsos__write_buildid_table(struct list_head *head, u16 misc, int fd)
205 dsos__for_each_with_build_id(pos, head) { 205 dsos__for_each_with_build_id(pos, head) {
206 int err; 206 int err;
207 struct build_id_event b; 207 struct build_id_event b;
208 size_t len = pos->long_name_len + 1; 208 size_t len;
209 209
210 if (!pos->hit)
211 continue;
212 len = pos->long_name_len + 1;
210 len = ALIGN(len, NAME_ALIGN); 213 len = ALIGN(len, NAME_ALIGN);
211 memset(&b, 0, sizeof(b)); 214 memset(&b, 0, sizeof(b));
212 memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id)); 215 memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id));
@@ -371,7 +374,7 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
371 u64 sec_start; 374 u64 sec_start;
372 int idx = 0, err; 375 int idx = 0, err;
373 376
374 if (dsos__read_build_ids()) 377 if (dsos__read_build_ids(true))
375 perf_header__set_feat(self, HEADER_BUILD_ID); 378 perf_header__set_feat(self, HEADER_BUILD_ID);
376 379
377 nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS); 380 nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index aa8a03120bbd..74cbc64a3a3c 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -385,8 +385,9 @@ static struct thread *perf_session__register_idle_thread(struct perf_session *se
385 return thread; 385 return thread;
386} 386}
387 387
388int perf_session__process_events(struct perf_session *self, 388int __perf_session__process_events(struct perf_session *self,
389 struct perf_event_ops *ops) 389 u64 data_offset, u64 data_size,
390 u64 file_size, struct perf_event_ops *ops)
390{ 391{
391 int err, mmap_prot, mmap_flags; 392 int err, mmap_prot, mmap_flags;
392 u64 head, shift; 393 u64 head, shift;
@@ -396,32 +397,11 @@ int perf_session__process_events(struct perf_session *self,
396 uint32_t size; 397 uint32_t size;
397 char *buf; 398 char *buf;
398 399
399 if (perf_session__register_idle_thread(self) == NULL)
400 return -ENOMEM;
401
402 perf_event_ops__fill_defaults(ops); 400 perf_event_ops__fill_defaults(ops);
403 401
404 page_size = sysconf(_SC_PAGESIZE); 402 page_size = sysconf(_SC_PAGESIZE);
405 403
406 head = self->header.data_offset; 404 head = data_offset;
407
408 if (!symbol_conf.full_paths) {
409 char bf[PATH_MAX];
410
411 if (getcwd(bf, sizeof(bf)) == NULL) {
412 err = -errno;
413out_getcwd_err:
414 pr_err("failed to get the current directory\n");
415 goto out_err;
416 }
417 self->cwd = strdup(bf);
418 if (self->cwd == NULL) {
419 err = -ENOMEM;
420 goto out_getcwd_err;
421 }
422 self->cwdlen = strlen(self->cwd);
423 }
424
425 shift = page_size * (head / page_size); 405 shift = page_size * (head / page_size);
426 offset += shift; 406 offset += shift;
427 head -= shift; 407 head -= shift;
@@ -486,10 +466,10 @@ more:
486 466
487 head += size; 467 head += size;
488 468
489 if (offset + head >= self->header.data_offset + self->header.data_size) 469 if (offset + head >= data_offset + data_size)
490 goto done; 470 goto done;
491 471
492 if (offset + head < self->size) 472 if (offset + head < file_size)
493 goto more; 473 goto more;
494done: 474done:
495 err = 0; 475 err = 0;
@@ -497,6 +477,38 @@ out_err:
497 return err; 477 return err;
498} 478}
499 479
480int perf_session__process_events(struct perf_session *self,
481 struct perf_event_ops *ops)
482{
483 int err;
484
485 if (perf_session__register_idle_thread(self) == NULL)
486 return -ENOMEM;
487
488 if (!symbol_conf.full_paths) {
489 char bf[PATH_MAX];
490
491 if (getcwd(bf, sizeof(bf)) == NULL) {
492 err = -errno;
493out_getcwd_err:
494 pr_err("failed to get the current directory\n");
495 goto out_err;
496 }
497 self->cwd = strdup(bf);
498 if (self->cwd == NULL) {
499 err = -ENOMEM;
500 goto out_getcwd_err;
501 }
502 self->cwdlen = strlen(self->cwd);
503 }
504
505 err = __perf_session__process_events(self, self->header.data_offset,
506 self->header.data_size,
507 self->size, ops);
508out_err:
509 return err;
510}
511
500bool perf_session__has_traces(struct perf_session *self, const char *msg) 512bool perf_session__has_traces(struct perf_session *self, const char *msg)
501{ 513{
502 if (!(self->sample_type & PERF_SAMPLE_RAW)) { 514 if (!(self->sample_type & PERF_SAMPLE_RAW)) {
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 752d75aebade..31950fcd8a4d 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -50,6 +50,9 @@ void perf_session__delete(struct perf_session *self);
50 50
51void perf_event_header__bswap(struct perf_event_header *self); 51void perf_event_header__bswap(struct perf_event_header *self);
52 52
53int __perf_session__process_events(struct perf_session *self,
54 u64 data_offset, u64 data_size, u64 size,
55 struct perf_event_ops *ops);
53int perf_session__process_events(struct perf_session *self, 56int perf_session__process_events(struct perf_session *self,
54 struct perf_event_ops *event_ops); 57 struct perf_event_ops *event_ops);
55 58
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e752837363ee..bfb055459670 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1076,25 +1076,28 @@ static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
1076 return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0; 1076 return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
1077} 1077}
1078 1078
1079static bool __dsos__read_build_ids(struct list_head *head) 1079static bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1080{ 1080{
1081 bool have_build_id = false; 1081 bool have_build_id = false;
1082 struct dso *pos; 1082 struct dso *pos;
1083 1083
1084 list_for_each_entry(pos, head, node) 1084 list_for_each_entry(pos, head, node) {
1085 if (with_hits && !pos->hit)
1086 continue;
1085 if (filename__read_build_id(pos->long_name, pos->build_id, 1087 if (filename__read_build_id(pos->long_name, pos->build_id,
1086 sizeof(pos->build_id)) > 0) { 1088 sizeof(pos->build_id)) > 0) {
1087 have_build_id = true; 1089 have_build_id = true;
1088 pos->has_build_id = true; 1090 pos->has_build_id = true;
1089 } 1091 }
1092 }
1090 1093
1091 return have_build_id; 1094 return have_build_id;
1092} 1095}
1093 1096
1094bool dsos__read_build_ids(void) 1097bool dsos__read_build_ids(bool with_hits)
1095{ 1098{
1096 bool kbuildids = __dsos__read_build_ids(&dsos__kernel), 1099 bool kbuildids = __dsos__read_build_ids(&dsos__kernel, with_hits),
1097 ubuildids = __dsos__read_build_ids(&dsos__user); 1100 ubuildids = __dsos__read_build_ids(&dsos__user, with_hits);
1098 return kbuildids || ubuildids; 1101 return kbuildids || ubuildids;
1099} 1102}
1100 1103
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index e90568a9e467..1b4192ee5300 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -157,7 +157,7 @@ struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
157 157
158int filename__read_build_id(const char *filename, void *bf, size_t size); 158int filename__read_build_id(const char *filename, void *bf, size_t size);
159int sysfs__read_build_id(const char *filename, void *bf, size_t size); 159int sysfs__read_build_id(const char *filename, void *bf, size_t size);
160bool dsos__read_build_ids(void); 160bool dsos__read_build_ids(bool with_hits);
161int build_id__sprintf(const u8 *self, int len, char *bf); 161int build_id__sprintf(const u8 *self, int len, char *bf);
162int kallsyms__parse(const char *filename, void *arg, 162int kallsyms__parse(const char *filename, void *arg,
163 int (*process_symbol)(void *arg, const char *name, 163 int (*process_symbol)(void *arg, const char *name,