aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-09-24 14:55:26 -0400
committerIngo Molnar <mingo@kernel.org>2012-09-24 14:55:26 -0400
commitf74eb728687afbf239abe2ea66921583db4eaa4b (patch)
tree47705ee82ead642e9a4b71edb39988c4b991a4ec /tools/perf/util
parent50a011f6409e888d5f41343024d24885281f048c (diff)
parentb1ac754b67b5a875d63bee880f60ccb0c6bd8899 (diff)
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: * Convert the trace builtins to use the growing evsel/evlist tracepoint infrastructure, removing several open coded constructs like switch like series of strcmp to dispatch events, etc. Basically what had already been showcased in 'perf sched'. * Add evsel constructor for tracepoints, that uses libtraceevent just to parse the /format events file, use it in a new 'perf test' to make sure the libtraceevent format parsing regressions can be more readily caught. * Some strange errors were happening in some builds, but not on the next, reported by several people, problem was some parser related files, generated during the build, didn't had proper make deps, fix from Eric Sandeen. * Fix some compiling errors on 32-bit, from Feng Tang. * Don't use sscanf extension %as, not available on bionic, reimplementation by Irina Tirdea. * Fix bfd.h/libbfd detection with recent binutils, from Markus Trippelsdorf. * Introduce struct and cache information about the environment where a perf.data file was captured, from Namhyung Kim. * Fix several error paths in libtraceevent, from Namhyung Kim. Print event causing perf_event_open() to fail in 'perf record', from Stephane Eranian. * New 'kvm' analysis tool, from Xiao Guangrong. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/evsel.c88
-rw-r--r--tools/perf/util/evsel.h5
-rw-r--r--tools/perf/util/header.c547
-rw-r--r--tools/perf/util/header.h24
-rw-r--r--tools/perf/util/map.c5
-rw-r--r--tools/perf/util/probe-event.c36
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c2
-rw-r--r--tools/perf/util/symbol.h1
-rw-r--r--tools/perf/util/thread.h2
-rw-r--r--tools/perf/util/trace-event-parse.c18
10 files changed, 538 insertions, 190 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 1506ba0453f1..00936ad29ff2 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -10,6 +10,7 @@
10#include <byteswap.h> 10#include <byteswap.h>
11#include <linux/bitops.h> 11#include <linux/bitops.h>
12#include "asm/bug.h" 12#include "asm/bug.h"
13#include "debugfs.h"
13#include "event-parse.h" 14#include "event-parse.h"
14#include "evsel.h" 15#include "evsel.h"
15#include "evlist.h" 16#include "evlist.h"
@@ -69,6 +70,72 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
69 return evsel; 70 return evsel;
70} 71}
71 72
73static struct event_format *event_format__new(const char *sys, const char *name)
74{
75 int fd, n;
76 char *filename;
77 void *bf = NULL, *nbf;
78 size_t size = 0, alloc_size = 0;
79 struct event_format *format = NULL;
80
81 if (asprintf(&filename, "%s/%s/%s/format", tracing_events_path, sys, name) < 0)
82 goto out;
83
84 fd = open(filename, O_RDONLY);
85 if (fd < 0)
86 goto out_free_filename;
87
88 do {
89 if (size == alloc_size) {
90 alloc_size += BUFSIZ;
91 nbf = realloc(bf, alloc_size);
92 if (nbf == NULL)
93 goto out_free_bf;
94 bf = nbf;
95 }
96
97 n = read(fd, bf + size, BUFSIZ);
98 if (n < 0)
99 goto out_free_bf;
100 size += n;
101 } while (n > 0);
102
103 pevent_parse_format(&format, bf, size, sys);
104
105out_free_bf:
106 free(bf);
107 close(fd);
108out_free_filename:
109 free(filename);
110out:
111 return format;
112}
113
114struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name, int idx)
115{
116 struct perf_evsel *evsel = zalloc(sizeof(*evsel));
117
118 if (evsel != NULL) {
119 struct perf_event_attr attr = {
120 .type = PERF_TYPE_TRACEPOINT,
121 };
122
123 evsel->tp_format = event_format__new(sys, name);
124 if (evsel->tp_format == NULL)
125 goto out_free;
126
127 attr.config = evsel->tp_format->id;
128 perf_evsel__init(evsel, &attr, idx);
129 evsel->name = evsel->tp_format->name;
130 }
131
132 return evsel;
133
134out_free:
135 free(evsel);
136 return NULL;
137}
138
72const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = { 139const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = {
73 "cycles", 140 "cycles",
74 "instructions", 141 "instructions",
@@ -495,6 +562,10 @@ void perf_evsel__delete(struct perf_evsel *evsel)
495 perf_evsel__exit(evsel); 562 perf_evsel__exit(evsel);
496 close_cgroup(evsel->cgrp); 563 close_cgroup(evsel->cgrp);
497 free(evsel->group_name); 564 free(evsel->group_name);
565 if (evsel->tp_format && evsel->name == evsel->tp_format->name) {
566 evsel->name = NULL;
567 pevent_free_format(evsel->tp_format);
568 }
498 free(evsel->name); 569 free(evsel->name);
499 free(evsel); 570 free(evsel);
500} 571}
@@ -1002,14 +1073,19 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
1002 return 0; 1073 return 0;
1003} 1074}
1004 1075
1076struct format_field *perf_evsel__field(struct perf_evsel *evsel, const char *name)
1077{
1078 return pevent_find_field(evsel->tp_format, name);
1079}
1080
1005char *perf_evsel__strval(struct perf_evsel *evsel, struct perf_sample *sample, 1081char *perf_evsel__strval(struct perf_evsel *evsel, struct perf_sample *sample,
1006 const char *name) 1082 const char *name)
1007{ 1083{
1008 struct format_field *field = pevent_find_field(evsel->tp_format, name); 1084 struct format_field *field = perf_evsel__field(evsel, name);
1009 int offset; 1085 int offset;
1010 1086
1011 if (!field) 1087 if (!field)
1012 return NULL; 1088 return NULL;
1013 1089
1014 offset = field->offset; 1090 offset = field->offset;
1015 1091
@@ -1024,11 +1100,11 @@ char *perf_evsel__strval(struct perf_evsel *evsel, struct perf_sample *sample,
1024u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, 1100u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample,
1025 const char *name) 1101 const char *name)
1026{ 1102{
1027 struct format_field *field = pevent_find_field(evsel->tp_format, name); 1103 struct format_field *field = perf_evsel__field(evsel, name);
1028 u64 val; 1104 u64 val;
1029 1105
1030 if (!field) 1106 if (!field)
1031 return 0; 1107 return 0;
1032 1108
1033 val = pevent_read_number(evsel->tp_format->pevent, 1109 val = pevent_read_number(evsel->tp_format->pevent,
1034 sample->raw_data + field->offset, field->size); 1110 sample->raw_data + field->offset, field->size);
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 93876bad2e52..bb445d1cbc7b 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -81,6 +81,7 @@ struct perf_evlist;
81struct perf_record_opts; 81struct perf_record_opts;
82 82
83struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx); 83struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx);
84struct perf_evsel *perf_evsel__newtp(const char *sys, const char *name, int idx);
84void perf_evsel__init(struct perf_evsel *evsel, 85void perf_evsel__init(struct perf_evsel *evsel,
85 struct perf_event_attr *attr, int idx); 86 struct perf_event_attr *attr, int idx);
86void perf_evsel__exit(struct perf_evsel *evsel); 87void perf_evsel__exit(struct perf_evsel *evsel);
@@ -128,6 +129,10 @@ char *perf_evsel__strval(struct perf_evsel *evsel, struct perf_sample *sample,
128u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, 129u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample,
129 const char *name); 130 const char *name);
130 131
132struct format_field;
133
134struct format_field *perf_evsel__field(struct perf_evsel *evsel, const char *name);
135
131#define perf_evsel__match(evsel, t, c) \ 136#define perf_evsel__match(evsel, t, c) \
132 (evsel->attr.type == PERF_TYPE_##t && \ 137 (evsel->attr.type == PERF_TYPE_##t && \
133 evsel->attr.config == PERF_COUNT_##c) 138 evsel->attr.config == PERF_COUNT_##c)
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index acbf6336199e..6aae3290358e 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -22,6 +22,7 @@
22#include "cpumap.h" 22#include "cpumap.h"
23#include "pmu.h" 23#include "pmu.h"
24#include "vdso.h" 24#include "vdso.h"
25#include "strbuf.h"
25 26
26static bool no_buildid_cache = false; 27static bool no_buildid_cache = false;
27 28
@@ -1102,118 +1103,80 @@ static int write_branch_stack(int fd __maybe_unused,
1102 return 0; 1103 return 0;
1103} 1104}
1104 1105
1105static void print_hostname(struct perf_header *ph, int fd, FILE *fp) 1106static void print_hostname(struct perf_header *ph, int fd __maybe_unused,
1107 FILE *fp)
1106{ 1108{
1107 char *str = do_read_string(fd, ph); 1109 fprintf(fp, "# hostname : %s\n", ph->env.hostname);
1108 fprintf(fp, "# hostname : %s\n", str);
1109 free(str);
1110} 1110}
1111 1111
1112static void print_osrelease(struct perf_header *ph, int fd, FILE *fp) 1112static void print_osrelease(struct perf_header *ph, int fd __maybe_unused,
1113 FILE *fp)
1113{ 1114{
1114 char *str = do_read_string(fd, ph); 1115 fprintf(fp, "# os release : %s\n", ph->env.os_release);
1115 fprintf(fp, "# os release : %s\n", str);
1116 free(str);
1117} 1116}
1118 1117
1119static void print_arch(struct perf_header *ph, int fd, FILE *fp) 1118static void print_arch(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
1120{ 1119{
1121 char *str = do_read_string(fd, ph); 1120 fprintf(fp, "# arch : %s\n", ph->env.arch);
1122 fprintf(fp, "# arch : %s\n", str);
1123 free(str);
1124} 1121}
1125 1122
1126static void print_cpudesc(struct perf_header *ph, int fd, FILE *fp) 1123static void print_cpudesc(struct perf_header *ph, int fd __maybe_unused,
1124 FILE *fp)
1127{ 1125{
1128 char *str = do_read_string(fd, ph); 1126 fprintf(fp, "# cpudesc : %s\n", ph->env.cpu_desc);
1129 fprintf(fp, "# cpudesc : %s\n", str);
1130 free(str);
1131} 1127}
1132 1128
1133static void print_nrcpus(struct perf_header *ph, int fd, FILE *fp) 1129static void print_nrcpus(struct perf_header *ph, int fd __maybe_unused,
1130 FILE *fp)
1134{ 1131{
1135 ssize_t ret; 1132 fprintf(fp, "# nrcpus online : %u\n", ph->env.nr_cpus_online);
1136 u32 nr; 1133 fprintf(fp, "# nrcpus avail : %u\n", ph->env.nr_cpus_avail);
1137
1138 ret = read(fd, &nr, sizeof(nr));
1139 if (ret != (ssize_t)sizeof(nr))
1140 nr = -1; /* interpreted as error */
1141
1142 if (ph->needs_swap)
1143 nr = bswap_32(nr);
1144
1145 fprintf(fp, "# nrcpus online : %u\n", nr);
1146
1147 ret = read(fd, &nr, sizeof(nr));
1148 if (ret != (ssize_t)sizeof(nr))
1149 nr = -1; /* interpreted as error */
1150
1151 if (ph->needs_swap)
1152 nr = bswap_32(nr);
1153
1154 fprintf(fp, "# nrcpus avail : %u\n", nr);
1155} 1134}
1156 1135
1157static void print_version(struct perf_header *ph, int fd, FILE *fp) 1136static void print_version(struct perf_header *ph, int fd __maybe_unused,
1137 FILE *fp)
1158{ 1138{
1159 char *str = do_read_string(fd, ph); 1139 fprintf(fp, "# perf version : %s\n", ph->env.version);
1160 fprintf(fp, "# perf version : %s\n", str);
1161 free(str);
1162} 1140}
1163 1141
1164static void print_cmdline(struct perf_header *ph, int fd, FILE *fp) 1142static void print_cmdline(struct perf_header *ph, int fd __maybe_unused,
1143 FILE *fp)
1165{ 1144{
1166 ssize_t ret; 1145 int nr, i;
1167 char *str; 1146 char *str;
1168 u32 nr, i;
1169
1170 ret = read(fd, &nr, sizeof(nr));
1171 if (ret != (ssize_t)sizeof(nr))
1172 return;
1173 1147
1174 if (ph->needs_swap) 1148 nr = ph->env.nr_cmdline;
1175 nr = bswap_32(nr); 1149 str = ph->env.cmdline;
1176 1150
1177 fprintf(fp, "# cmdline : "); 1151 fprintf(fp, "# cmdline : ");
1178 1152
1179 for (i = 0; i < nr; i++) { 1153 for (i = 0; i < nr; i++) {
1180 str = do_read_string(fd, ph);
1181 fprintf(fp, "%s ", str); 1154 fprintf(fp, "%s ", str);
1182 free(str); 1155 str += strlen(str) + 1;
1183 } 1156 }
1184 fputc('\n', fp); 1157 fputc('\n', fp);
1185} 1158}
1186 1159
1187static void print_cpu_topology(struct perf_header *ph, int fd, FILE *fp) 1160static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused,
1161 FILE *fp)
1188{ 1162{
1189 ssize_t ret; 1163 int nr, i;
1190 u32 nr, i;
1191 char *str; 1164 char *str;
1192 1165
1193 ret = read(fd, &nr, sizeof(nr)); 1166 nr = ph->env.nr_sibling_cores;
1194 if (ret != (ssize_t)sizeof(nr)) 1167 str = ph->env.sibling_cores;
1195 return;
1196
1197 if (ph->needs_swap)
1198 nr = bswap_32(nr);
1199 1168
1200 for (i = 0; i < nr; i++) { 1169 for (i = 0; i < nr; i++) {
1201 str = do_read_string(fd, ph);
1202 fprintf(fp, "# sibling cores : %s\n", str); 1170 fprintf(fp, "# sibling cores : %s\n", str);
1203 free(str); 1171 str += strlen(str) + 1;
1204 } 1172 }
1205 1173
1206 ret = read(fd, &nr, sizeof(nr)); 1174 nr = ph->env.nr_sibling_threads;
1207 if (ret != (ssize_t)sizeof(nr)) 1175 str = ph->env.sibling_threads;
1208 return;
1209
1210 if (ph->needs_swap)
1211 nr = bswap_32(nr);
1212 1176
1213 for (i = 0; i < nr; i++) { 1177 for (i = 0; i < nr; i++) {
1214 str = do_read_string(fd, ph);
1215 fprintf(fp, "# sibling threads : %s\n", str); 1178 fprintf(fp, "# sibling threads : %s\n", str);
1216 free(str); 1179 str += strlen(str) + 1;
1217 } 1180 }
1218} 1181}
1219 1182
@@ -1374,126 +1337,89 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
1374 free_event_desc(events); 1337 free_event_desc(events);
1375} 1338}
1376 1339
1377static void print_total_mem(struct perf_header *h __maybe_unused, int fd, 1340static void print_total_mem(struct perf_header *ph, int fd __maybe_unused,
1378 FILE *fp) 1341 FILE *fp)
1379{ 1342{
1380 uint64_t mem; 1343 fprintf(fp, "# total memory : %Lu kB\n", ph->env.total_mem);
1381 ssize_t ret;
1382
1383 ret = read(fd, &mem, sizeof(mem));
1384 if (ret != sizeof(mem))
1385 goto error;
1386
1387 if (h->needs_swap)
1388 mem = bswap_64(mem);
1389
1390 fprintf(fp, "# total memory : %"PRIu64" kB\n", mem);
1391 return;
1392error:
1393 fprintf(fp, "# total memory : unknown\n");
1394} 1344}
1395 1345
1396static void print_numa_topology(struct perf_header *h __maybe_unused, int fd, 1346static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused,
1397 FILE *fp) 1347 FILE *fp)
1398{ 1348{
1399 ssize_t ret;
1400 u32 nr, c, i; 1349 u32 nr, c, i;
1401 char *str; 1350 char *str, *tmp;
1402 uint64_t mem_total, mem_free; 1351 uint64_t mem_total, mem_free;
1403 1352
1404 /* nr nodes */ 1353 /* nr nodes */
1405 ret = read(fd, &nr, sizeof(nr)); 1354 nr = ph->env.nr_numa_nodes;
1406 if (ret != (ssize_t)sizeof(nr)) 1355 str = ph->env.numa_nodes;
1407 goto error;
1408
1409 if (h->needs_swap)
1410 nr = bswap_32(nr);
1411 1356
1412 for (i = 0; i < nr; i++) { 1357 for (i = 0; i < nr; i++) {
1413
1414 /* node number */ 1358 /* node number */
1415 ret = read(fd, &c, sizeof(c)); 1359 c = strtoul(str, &tmp, 0);
1416 if (ret != (ssize_t)sizeof(c)) 1360 if (*tmp != ':')
1417 goto error; 1361 goto error;
1418 1362
1419 if (h->needs_swap) 1363 str = tmp + 1;
1420 c = bswap_32(c); 1364 mem_total = strtoull(str, &tmp, 0);
1421 1365 if (*tmp != ':')
1422 ret = read(fd, &mem_total, sizeof(u64));
1423 if (ret != sizeof(u64))
1424 goto error; 1366 goto error;
1425 1367
1426 ret = read(fd, &mem_free, sizeof(u64)); 1368 str = tmp + 1;
1427 if (ret != sizeof(u64)) 1369 mem_free = strtoull(str, &tmp, 0);
1370 if (*tmp != ':')
1428 goto error; 1371 goto error;
1429 1372
1430 if (h->needs_swap) {
1431 mem_total = bswap_64(mem_total);
1432 mem_free = bswap_64(mem_free);
1433 }
1434
1435 fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB," 1373 fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB,"
1436 " free = %"PRIu64" kB\n", 1374 " free = %"PRIu64" kB\n",
1437 c, 1375 c, mem_total, mem_free);
1438 mem_total,
1439 mem_free);
1440 1376
1441 str = do_read_string(fd, h); 1377 str = tmp + 1;
1442 fprintf(fp, "# node%u cpu list : %s\n", c, str); 1378 fprintf(fp, "# node%u cpu list : %s\n", c, str);
1443 free(str);
1444 } 1379 }
1445 return; 1380 return;
1446error: 1381error:
1447 fprintf(fp, "# numa topology : not available\n"); 1382 fprintf(fp, "# numa topology : not available\n");
1448} 1383}
1449 1384
1450static void print_cpuid(struct perf_header *ph, int fd, FILE *fp) 1385static void print_cpuid(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
1451{ 1386{
1452 char *str = do_read_string(fd, ph); 1387 fprintf(fp, "# cpuid : %s\n", ph->env.cpuid);
1453 fprintf(fp, "# cpuid : %s\n", str);
1454 free(str);
1455} 1388}
1456 1389
1457static void print_branch_stack(struct perf_header *ph __maybe_unused, 1390static void print_branch_stack(struct perf_header *ph __maybe_unused,
1458 int fd __maybe_unused, 1391 int fd __maybe_unused, FILE *fp)
1459 FILE *fp)
1460{ 1392{
1461 fprintf(fp, "# contains samples with branch stack\n"); 1393 fprintf(fp, "# contains samples with branch stack\n");
1462} 1394}
1463 1395
1464static void print_pmu_mappings(struct perf_header *ph, int fd, FILE *fp) 1396static void print_pmu_mappings(struct perf_header *ph, int fd __maybe_unused,
1397 FILE *fp)
1465{ 1398{
1466 const char *delimiter = "# pmu mappings: "; 1399 const char *delimiter = "# pmu mappings: ";
1467 char *name; 1400 char *str, *tmp;
1468 int ret;
1469 u32 pmu_num; 1401 u32 pmu_num;
1470 u32 type; 1402 u32 type;
1471 1403
1472 ret = read(fd, &pmu_num, sizeof(pmu_num)); 1404 pmu_num = ph->env.nr_pmu_mappings;
1473 if (ret != sizeof(pmu_num))
1474 goto error;
1475
1476 if (ph->needs_swap)
1477 pmu_num = bswap_32(pmu_num);
1478
1479 if (!pmu_num) { 1405 if (!pmu_num) {
1480 fprintf(fp, "# pmu mappings: not available\n"); 1406 fprintf(fp, "# pmu mappings: not available\n");
1481 return; 1407 return;
1482 } 1408 }
1483 1409
1410 str = ph->env.pmu_mappings;
1411
1484 while (pmu_num) { 1412 while (pmu_num) {
1485 if (read(fd, &type, sizeof(type)) != sizeof(type)) 1413 type = strtoul(str, &tmp, 0);
1486 break; 1414 if (*tmp != ':')
1487 if (ph->needs_swap) 1415 goto error;
1488 type = bswap_32(type); 1416
1417 str = tmp + 1;
1418 fprintf(fp, "%s%s = %" PRIu32, delimiter, str, type);
1489 1419
1490 name = do_read_string(fd, ph);
1491 if (!name)
1492 break;
1493 pmu_num--;
1494 fprintf(fp, "%s%s = %" PRIu32, delimiter, name, type);
1495 free(name);
1496 delimiter = ", "; 1420 delimiter = ", ";
1421 str += strlen(str) + 1;
1422 pmu_num--;
1497 } 1423 }
1498 1424
1499 fprintf(fp, "\n"); 1425 fprintf(fp, "\n");
@@ -1654,18 +1580,16 @@ out:
1654 return err; 1580 return err;
1655} 1581}
1656 1582
1657static int process_tracing_data(struct perf_file_section *section 1583static int process_tracing_data(struct perf_file_section *section __maybe_unused,
1658 __maybe_unused, 1584 struct perf_header *ph __maybe_unused,
1659 struct perf_header *ph __maybe_unused, 1585 int fd, void *data)
1660 int feat __maybe_unused, int fd, void *data)
1661{ 1586{
1662 trace_report(fd, data, false); 1587 trace_report(fd, data, false);
1663 return 0; 1588 return 0;
1664} 1589}
1665 1590
1666static int process_build_id(struct perf_file_section *section, 1591static int process_build_id(struct perf_file_section *section,
1667 struct perf_header *ph, 1592 struct perf_header *ph, int fd,
1668 int feat __maybe_unused, int fd,
1669 void *data __maybe_unused) 1593 void *data __maybe_unused)
1670{ 1594{
1671 if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) 1595 if (perf_header__read_build_ids(ph, fd, section->offset, section->size))
@@ -1673,6 +1597,99 @@ static int process_build_id(struct perf_file_section *section,
1673 return 0; 1597 return 0;
1674} 1598}
1675 1599
1600static int process_hostname(struct perf_file_section *section __maybe_unused,
1601 struct perf_header *ph, int fd,
1602 void *data __maybe_unused)
1603{
1604 ph->env.hostname = do_read_string(fd, ph);
1605 return ph->env.hostname ? 0 : -ENOMEM;
1606}
1607
1608static int process_osrelease(struct perf_file_section *section __maybe_unused,
1609 struct perf_header *ph, int fd,
1610 void *data __maybe_unused)
1611{
1612 ph->env.os_release = do_read_string(fd, ph);
1613 return ph->env.os_release ? 0 : -ENOMEM;
1614}
1615
1616static int process_version(struct perf_file_section *section __maybe_unused,
1617 struct perf_header *ph, int fd,
1618 void *data __maybe_unused)
1619{
1620 ph->env.version = do_read_string(fd, ph);
1621 return ph->env.version ? 0 : -ENOMEM;
1622}
1623
1624static int process_arch(struct perf_file_section *section __maybe_unused,
1625 struct perf_header *ph, int fd,
1626 void *data __maybe_unused)
1627{
1628 ph->env.arch = do_read_string(fd, ph);
1629 return ph->env.arch ? 0 : -ENOMEM;
1630}
1631
1632static int process_nrcpus(struct perf_file_section *section __maybe_unused,
1633 struct perf_header *ph, int fd,
1634 void *data __maybe_unused)
1635{
1636 size_t ret;
1637 u32 nr;
1638
1639 ret = read(fd, &nr, sizeof(nr));
1640 if (ret != sizeof(nr))
1641 return -1;
1642
1643 if (ph->needs_swap)
1644 nr = bswap_32(nr);
1645
1646 ph->env.nr_cpus_online = nr;
1647
1648 ret = read(fd, &nr, sizeof(nr));
1649 if (ret != sizeof(nr))
1650 return -1;
1651
1652 if (ph->needs_swap)
1653 nr = bswap_32(nr);
1654
1655 ph->env.nr_cpus_avail = nr;
1656 return 0;
1657}
1658
1659static int process_cpudesc(struct perf_file_section *section __maybe_unused,
1660 struct perf_header *ph, int fd,
1661 void *data __maybe_unused)
1662{
1663 ph->env.cpu_desc = do_read_string(fd, ph);
1664 return ph->env.cpu_desc ? 0 : -ENOMEM;
1665}
1666
1667static int process_cpuid(struct perf_file_section *section __maybe_unused,
1668 struct perf_header *ph, int fd,
1669 void *data __maybe_unused)
1670{
1671 ph->env.cpuid = do_read_string(fd, ph);
1672 return ph->env.cpuid ? 0 : -ENOMEM;
1673}
1674
1675static int process_total_mem(struct perf_file_section *section __maybe_unused,
1676 struct perf_header *ph, int fd,
1677 void *data __maybe_unused)
1678{
1679 uint64_t mem;
1680 size_t ret;
1681
1682 ret = read(fd, &mem, sizeof(mem));
1683 if (ret != sizeof(mem))
1684 return -1;
1685
1686 if (ph->needs_swap)
1687 mem = bswap_64(mem);
1688
1689 ph->env.total_mem = mem;
1690 return 0;
1691}
1692
1676static struct perf_evsel * 1693static struct perf_evsel *
1677perf_evlist__find_by_index(struct perf_evlist *evlist, int idx) 1694perf_evlist__find_by_index(struct perf_evlist *evlist, int idx)
1678{ 1695{
@@ -1687,7 +1704,8 @@ perf_evlist__find_by_index(struct perf_evlist *evlist, int idx)
1687} 1704}
1688 1705
1689static void 1706static void
1690perf_evlist__set_event_name(struct perf_evlist *evlist, struct perf_evsel *event) 1707perf_evlist__set_event_name(struct perf_evlist *evlist,
1708 struct perf_evsel *event)
1691{ 1709{
1692 struct perf_evsel *evsel; 1710 struct perf_evsel *evsel;
1693 1711
@@ -1706,15 +1724,16 @@ perf_evlist__set_event_name(struct perf_evlist *evlist, struct perf_evsel *event
1706 1724
1707static int 1725static int
1708process_event_desc(struct perf_file_section *section __maybe_unused, 1726process_event_desc(struct perf_file_section *section __maybe_unused,
1709 struct perf_header *header, int feat __maybe_unused, int fd, 1727 struct perf_header *header, int fd,
1710 void *data __maybe_unused) 1728 void *data __maybe_unused)
1711{ 1729{
1712 struct perf_session *session = container_of(header, struct perf_session, header); 1730 struct perf_session *session;
1713 struct perf_evsel *evsel, *events = read_event_desc(header, fd); 1731 struct perf_evsel *evsel, *events = read_event_desc(header, fd);
1714 1732
1715 if (!events) 1733 if (!events)
1716 return 0; 1734 return 0;
1717 1735
1736 session = container_of(header, struct perf_session, header);
1718 for (evsel = events; evsel->attr.size; evsel++) 1737 for (evsel = events; evsel->attr.size; evsel++)
1719 perf_evlist__set_event_name(session->evlist, evsel); 1738 perf_evlist__set_event_name(session->evlist, evsel);
1720 1739
@@ -1723,11 +1742,213 @@ process_event_desc(struct perf_file_section *section __maybe_unused,
1723 return 0; 1742 return 0;
1724} 1743}
1725 1744
1745static int process_cmdline(struct perf_file_section *section __maybe_unused,
1746 struct perf_header *ph, int fd,
1747 void *data __maybe_unused)
1748{
1749 size_t ret;
1750 char *str;
1751 u32 nr, i;
1752 struct strbuf sb;
1753
1754 ret = read(fd, &nr, sizeof(nr));
1755 if (ret != sizeof(nr))
1756 return -1;
1757
1758 if (ph->needs_swap)
1759 nr = bswap_32(nr);
1760
1761 ph->env.nr_cmdline = nr;
1762 strbuf_init(&sb, 128);
1763
1764 for (i = 0; i < nr; i++) {
1765 str = do_read_string(fd, ph);
1766 if (!str)
1767 goto error;
1768
1769 /* include a NULL character at the end */
1770 strbuf_add(&sb, str, strlen(str) + 1);
1771 free(str);
1772 }
1773 ph->env.cmdline = strbuf_detach(&sb, NULL);
1774 return 0;
1775
1776error:
1777 strbuf_release(&sb);
1778 return -1;
1779}
1780
1781static int process_cpu_topology(struct perf_file_section *section __maybe_unused,
1782 struct perf_header *ph, int fd,
1783 void *data __maybe_unused)
1784{
1785 size_t ret;
1786 u32 nr, i;
1787 char *str;
1788 struct strbuf sb;
1789
1790 ret = read(fd, &nr, sizeof(nr));
1791 if (ret != sizeof(nr))
1792 return -1;
1793
1794 if (ph->needs_swap)
1795 nr = bswap_32(nr);
1796
1797 ph->env.nr_sibling_cores = nr;
1798 strbuf_init(&sb, 128);
1799
1800 for (i = 0; i < nr; i++) {
1801 str = do_read_string(fd, ph);
1802 if (!str)
1803 goto error;
1804
1805 /* include a NULL character at the end */
1806 strbuf_add(&sb, str, strlen(str) + 1);
1807 free(str);
1808 }
1809 ph->env.sibling_cores = strbuf_detach(&sb, NULL);
1810
1811 ret = read(fd, &nr, sizeof(nr));
1812 if (ret != sizeof(nr))
1813 return -1;
1814
1815 if (ph->needs_swap)
1816 nr = bswap_32(nr);
1817
1818 ph->env.nr_sibling_threads = nr;
1819
1820 for (i = 0; i < nr; i++) {
1821 str = do_read_string(fd, ph);
1822 if (!str)
1823 goto error;
1824
1825 /* include a NULL character at the end */
1826 strbuf_add(&sb, str, strlen(str) + 1);
1827 free(str);
1828 }
1829 ph->env.sibling_threads = strbuf_detach(&sb, NULL);
1830 return 0;
1831
1832error:
1833 strbuf_release(&sb);
1834 return -1;
1835}
1836
1837static int process_numa_topology(struct perf_file_section *section __maybe_unused,
1838 struct perf_header *ph, int fd,
1839 void *data __maybe_unused)
1840{
1841 size_t ret;
1842 u32 nr, node, i;
1843 char *str;
1844 uint64_t mem_total, mem_free;
1845 struct strbuf sb;
1846
1847 /* nr nodes */
1848 ret = read(fd, &nr, sizeof(nr));
1849 if (ret != sizeof(nr))
1850 goto error;
1851
1852 if (ph->needs_swap)
1853 nr = bswap_32(nr);
1854
1855 ph->env.nr_numa_nodes = nr;
1856 strbuf_init(&sb, 256);
1857
1858 for (i = 0; i < nr; i++) {
1859 /* node number */
1860 ret = read(fd, &node, sizeof(node));
1861 if (ret != sizeof(node))
1862 goto error;
1863
1864 ret = read(fd, &mem_total, sizeof(u64));
1865 if (ret != sizeof(u64))
1866 goto error;
1867
1868 ret = read(fd, &mem_free, sizeof(u64));
1869 if (ret != sizeof(u64))
1870 goto error;
1871
1872 if (ph->needs_swap) {
1873 node = bswap_32(node);
1874 mem_total = bswap_64(mem_total);
1875 mem_free = bswap_64(mem_free);
1876 }
1877
1878 strbuf_addf(&sb, "%u:%"PRIu64":%"PRIu64":",
1879 node, mem_total, mem_free);
1880
1881 str = do_read_string(fd, ph);
1882 if (!str)
1883 goto error;
1884
1885 /* include a NULL character at the end */
1886 strbuf_add(&sb, str, strlen(str) + 1);
1887 free(str);
1888 }
1889 ph->env.numa_nodes = strbuf_detach(&sb, NULL);
1890 return 0;
1891
1892error:
1893 strbuf_release(&sb);
1894 return -1;
1895}
1896
1897static int process_pmu_mappings(struct perf_file_section *section __maybe_unused,
1898 struct perf_header *ph, int fd,
1899 void *data __maybe_unused)
1900{
1901 size_t ret;
1902 char *name;
1903 u32 pmu_num;
1904 u32 type;
1905 struct strbuf sb;
1906
1907 ret = read(fd, &pmu_num, sizeof(pmu_num));
1908 if (ret != sizeof(pmu_num))
1909 return -1;
1910
1911 if (ph->needs_swap)
1912 pmu_num = bswap_32(pmu_num);
1913
1914 if (!pmu_num) {
1915 pr_debug("pmu mappings not available\n");
1916 return 0;
1917 }
1918
1919 ph->env.nr_pmu_mappings = pmu_num;
1920 strbuf_init(&sb, 128);
1921
1922 while (pmu_num) {
1923 if (read(fd, &type, sizeof(type)) != sizeof(type))
1924 goto error;
1925 if (ph->needs_swap)
1926 type = bswap_32(type);
1927
1928 name = do_read_string(fd, ph);
1929 if (!name)
1930 goto error;
1931
1932 strbuf_addf(&sb, "%u:%s", type, name);
1933 /* include a NULL character at the end */
1934 strbuf_add(&sb, "", 1);
1935
1936 free(name);
1937 pmu_num--;
1938 }
1939 ph->env.pmu_mappings = strbuf_detach(&sb, NULL);
1940 return 0;
1941
1942error:
1943 strbuf_release(&sb);
1944 return -1;
1945}
1946
1726struct feature_ops { 1947struct feature_ops {
1727 int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); 1948 int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist);
1728 void (*print)(struct perf_header *h, int fd, FILE *fp); 1949 void (*print)(struct perf_header *h, int fd, FILE *fp);
1729 int (*process)(struct perf_file_section *section, 1950 int (*process)(struct perf_file_section *section,
1730 struct perf_header *h, int feat, int fd, void *data); 1951 struct perf_header *h, int fd, void *data);
1731 const char *name; 1952 const char *name;
1732 bool full_only; 1953 bool full_only;
1733}; 1954};
@@ -1739,7 +1960,7 @@ struct feature_ops {
1739 .process = process_##func } 1960 .process = process_##func }
1740#define FEAT_OPF(n, func) \ 1961#define FEAT_OPF(n, func) \
1741 [n] = { .name = #n, .write = write_##func, .print = print_##func, \ 1962 [n] = { .name = #n, .write = write_##func, .print = print_##func, \
1742 .full_only = true } 1963 .process = process_##func, .full_only = true }
1743 1964
1744/* feature_ops not implemented: */ 1965/* feature_ops not implemented: */
1745#define print_tracing_data NULL 1966#define print_tracing_data NULL
@@ -1748,20 +1969,20 @@ struct feature_ops {
1748static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { 1969static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
1749 FEAT_OPP(HEADER_TRACING_DATA, tracing_data), 1970 FEAT_OPP(HEADER_TRACING_DATA, tracing_data),
1750 FEAT_OPP(HEADER_BUILD_ID, build_id), 1971 FEAT_OPP(HEADER_BUILD_ID, build_id),
1751 FEAT_OPA(HEADER_HOSTNAME, hostname), 1972 FEAT_OPP(HEADER_HOSTNAME, hostname),
1752 FEAT_OPA(HEADER_OSRELEASE, osrelease), 1973 FEAT_OPP(HEADER_OSRELEASE, osrelease),
1753 FEAT_OPA(HEADER_VERSION, version), 1974 FEAT_OPP(HEADER_VERSION, version),
1754 FEAT_OPA(HEADER_ARCH, arch), 1975 FEAT_OPP(HEADER_ARCH, arch),
1755 FEAT_OPA(HEADER_NRCPUS, nrcpus), 1976 FEAT_OPP(HEADER_NRCPUS, nrcpus),
1756 FEAT_OPA(HEADER_CPUDESC, cpudesc), 1977 FEAT_OPP(HEADER_CPUDESC, cpudesc),
1757 FEAT_OPA(HEADER_CPUID, cpuid), 1978 FEAT_OPP(HEADER_CPUID, cpuid),
1758 FEAT_OPA(HEADER_TOTAL_MEM, total_mem), 1979 FEAT_OPP(HEADER_TOTAL_MEM, total_mem),
1759 FEAT_OPP(HEADER_EVENT_DESC, event_desc), 1980 FEAT_OPP(HEADER_EVENT_DESC, event_desc),
1760 FEAT_OPA(HEADER_CMDLINE, cmdline), 1981 FEAT_OPP(HEADER_CMDLINE, cmdline),
1761 FEAT_OPF(HEADER_CPU_TOPOLOGY, cpu_topology), 1982 FEAT_OPF(HEADER_CPU_TOPOLOGY, cpu_topology),
1762 FEAT_OPF(HEADER_NUMA_TOPOLOGY, numa_topology), 1983 FEAT_OPF(HEADER_NUMA_TOPOLOGY, numa_topology),
1763 FEAT_OPA(HEADER_BRANCH_STACK, branch_stack), 1984 FEAT_OPA(HEADER_BRANCH_STACK, branch_stack),
1764 FEAT_OPA(HEADER_PMU_MAPPINGS, pmu_mappings), 1985 FEAT_OPP(HEADER_PMU_MAPPINGS, pmu_mappings),
1765}; 1986};
1766 1987
1767struct header_print_data { 1988struct header_print_data {
@@ -2241,7 +2462,7 @@ static int perf_file_section__process(struct perf_file_section *section,
2241 if (!feat_ops[feat].process) 2462 if (!feat_ops[feat].process)
2242 return 0; 2463 return 0;
2243 2464
2244 return feat_ops[feat].process(section, ph, feat, fd, data); 2465 return feat_ops[feat].process(section, ph, fd, data);
2245} 2466}
2246 2467
2247static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, 2468static int perf_file_header__read_pipe(struct perf_pipe_file_header *header,
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 209dad4fee2b..99bdd3abce59 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -58,6 +58,29 @@ struct perf_header;
58int perf_file_header__read(struct perf_file_header *header, 58int perf_file_header__read(struct perf_file_header *header,
59 struct perf_header *ph, int fd); 59 struct perf_header *ph, int fd);
60 60
61struct perf_session_env {
62 char *hostname;
63 char *os_release;
64 char *version;
65 char *arch;
66 int nr_cpus_online;
67 int nr_cpus_avail;
68 char *cpu_desc;
69 char *cpuid;
70 unsigned long long total_mem;
71
72 int nr_cmdline;
73 char *cmdline;
74 int nr_sibling_cores;
75 char *sibling_cores;
76 int nr_sibling_threads;
77 char *sibling_threads;
78 int nr_numa_nodes;
79 char *numa_nodes;
80 int nr_pmu_mappings;
81 char *pmu_mappings;
82};
83
61struct perf_header { 84struct perf_header {
62 int frozen; 85 int frozen;
63 bool needs_swap; 86 bool needs_swap;
@@ -67,6 +90,7 @@ struct perf_header {
67 u64 event_offset; 90 u64 event_offset;
68 u64 event_size; 91 u64 event_size;
69 DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS); 92 DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
93 struct perf_session_env env;
70}; 94};
71 95
72struct perf_evlist; 96struct perf_evlist;
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index b442ee49452b..ead5316b3f89 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -243,15 +243,14 @@ size_t map__fprintf(struct map *self, FILE *fp)
243 243
244size_t map__fprintf_dsoname(struct map *map, FILE *fp) 244size_t map__fprintf_dsoname(struct map *map, FILE *fp)
245{ 245{
246 const char *dsoname; 246 const char *dsoname = "[unknown]";
247 247
248 if (map && map->dso && (map->dso->name || map->dso->long_name)) { 248 if (map && map->dso && (map->dso->name || map->dso->long_name)) {
249 if (symbol_conf.show_kernel_path && map->dso->long_name) 249 if (symbol_conf.show_kernel_path && map->dso->long_name)
250 dsoname = map->dso->long_name; 250 dsoname = map->dso->long_name;
251 else if (map->dso->name) 251 else if (map->dso->name)
252 dsoname = map->dso->name; 252 dsoname = map->dso->name;
253 } else 253 }
254 dsoname = "[unknown]";
255 254
256 return fprintf(fp, "%s", dsoname); 255 return fprintf(fp, "%s", dsoname);
257} 256}
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 4ce04c2281d3..49a256e6e0a2 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1100,6 +1100,7 @@ static int parse_probe_trace_command(const char *cmd,
1100 struct probe_trace_point *tp = &tev->point; 1100 struct probe_trace_point *tp = &tev->point;
1101 char pr; 1101 char pr;
1102 char *p; 1102 char *p;
1103 char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str;
1103 int ret, i, argc; 1104 int ret, i, argc;
1104 char **argv; 1105 char **argv;
1105 1106
@@ -1116,14 +1117,27 @@ static int parse_probe_trace_command(const char *cmd,
1116 } 1117 }
1117 1118
1118 /* Scan event and group name. */ 1119 /* Scan event and group name. */
1119 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", 1120 argv0_str = strdup(argv[0]);
1120 &pr, (float *)(void *)&tev->group, 1121 if (argv0_str == NULL) {
1121 (float *)(void *)&tev->event); 1122 ret = -ENOMEM;
1122 if (ret != 3) { 1123 goto out;
1124 }
1125 fmt1_str = strtok_r(argv0_str, ":", &fmt);
1126 fmt2_str = strtok_r(NULL, "/", &fmt);
1127 fmt3_str = strtok_r(NULL, " \t", &fmt);
1128 if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL
1129 || fmt3_str == NULL) {
1123 semantic_error("Failed to parse event name: %s\n", argv[0]); 1130 semantic_error("Failed to parse event name: %s\n", argv[0]);
1124 ret = -EINVAL; 1131 ret = -EINVAL;
1125 goto out; 1132 goto out;
1126 } 1133 }
1134 pr = fmt1_str[0];
1135 tev->group = strdup(fmt2_str);
1136 tev->event = strdup(fmt3_str);
1137 if (tev->group == NULL || tev->event == NULL) {
1138 ret = -ENOMEM;
1139 goto out;
1140 }
1127 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); 1141 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
1128 1142
1129 tp->retprobe = (pr == 'r'); 1143 tp->retprobe = (pr == 'r');
@@ -1135,10 +1149,17 @@ static int parse_probe_trace_command(const char *cmd,
1135 p++; 1149 p++;
1136 } else 1150 } else
1137 p = argv[1]; 1151 p = argv[1];
1138 ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol, 1152 fmt1_str = strtok_r(p, "+", &fmt);
1139 &tp->offset); 1153 tp->symbol = strdup(fmt1_str);
1140 if (ret == 1) 1154 if (tp->symbol == NULL) {
1155 ret = -ENOMEM;
1156 goto out;
1157 }
1158 fmt2_str = strtok_r(NULL, "", &fmt);
1159 if (fmt2_str == NULL)
1141 tp->offset = 0; 1160 tp->offset = 0;
1161 else
1162 tp->offset = strtoul(fmt2_str, NULL, 10);
1142 1163
1143 tev->nargs = argc - 2; 1164 tev->nargs = argc - 2;
1144 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); 1165 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
@@ -1162,6 +1183,7 @@ static int parse_probe_trace_command(const char *cmd,
1162 } 1183 }
1163 ret = 0; 1184 ret = 0;
1164out: 1185out:
1186 free(argv0_str);
1165 argv_free(argv); 1187 argv_free(argv);
1166 return ret; 1188 return ret;
1167} 1189}
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index ffde3e4e34aa..f80605eb1855 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -282,7 +282,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __maybe_unused,
282 282
283 event = find_cache_event(evsel); 283 event = find_cache_event(evsel);
284 if (!event) 284 if (!event)
285 die("ug! no event found for type %d", evsel->attr.config); 285 die("ug! no event found for type %" PRIu64, evsel->attr.config);
286 286
287 pid = raw_field_value(event, "common_pid", data); 287 pid = raw_field_value(event, "common_pid", data);
288 288
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 4ff45e30c726..b441b07172b7 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -34,6 +34,7 @@ static inline char *bfd_demangle(void __maybe_unused *v,
34 return NULL; 34 return NULL;
35} 35}
36#else 36#else
37#define PACKAGE 'perf'
37#include <bfd.h> 38#include <bfd.h>
38#endif 39#endif
39#endif 40#endif
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 70c2c13ff679..f66610b7bacf 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -16,6 +16,8 @@ struct thread {
16 bool comm_set; 16 bool comm_set;
17 char *comm; 17 char *comm;
18 int comm_len; 18 int comm_len;
19
20 void *priv;
19}; 21};
20 22
21struct machine; 23struct machine;
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index aa4c860a21d1..3aabcd687cd5 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -229,24 +229,22 @@ void parse_proc_kallsyms(struct pevent *pevent,
229 char *next = NULL; 229 char *next = NULL;
230 char *addr_str; 230 char *addr_str;
231 char *mod; 231 char *mod;
232 char ch; 232 char *fmt;
233 233
234 line = strtok_r(file, "\n", &next); 234 line = strtok_r(file, "\n", &next);
235 while (line) { 235 while (line) {
236 mod = NULL; 236 mod = NULL;
237 sscanf(line, "%as %c %as\t[%as", 237 addr_str = strtok_r(line, " ", &fmt);
238 (float *)(void *)&addr_str, /* workaround gcc warning */
239 &ch, (float *)(void *)&func, (float *)(void *)&mod);
240 addr = strtoull(addr_str, NULL, 16); 238 addr = strtoull(addr_str, NULL, 16);
241 free(addr_str); 239 /* skip character */
242 240 strtok_r(NULL, " ", &fmt);
243 /* truncate the extra ']' */ 241 func = strtok_r(NULL, "\t", &fmt);
242 mod = strtok_r(NULL, "]", &fmt);
243 /* truncate the extra '[' */
244 if (mod) 244 if (mod)
245 mod[strlen(mod) - 1] = 0; 245 mod = mod + 1;
246 246
247 pevent_register_function(pevent, func, addr, mod); 247 pevent_register_function(pevent, func, addr, mod);
248 free(func);
249 free(mod);
250 248
251 line = strtok_r(NULL, "\n", &next); 249 line = strtok_r(NULL, "\n", &next);
252 } 250 }