aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/header.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/header.c')
-rw-r--r--tools/perf/util/header.c74
1 files changed, 65 insertions, 9 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index e306857b2c2b..7d26659b806c 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -5,6 +5,8 @@
5 5
6#include "util.h" 6#include "util.h"
7#include "header.h" 7#include "header.h"
8#include "../perf.h"
9#include "trace-event.h"
8 10
9/* 11/*
10 * Create new perf.data header attribute: 12 * Create new perf.data header attribute:
@@ -46,23 +48,17 @@ void perf_header_attr__add_id(struct perf_header_attr *self, u64 id)
46 */ 48 */
47struct perf_header *perf_header__new(void) 49struct perf_header *perf_header__new(void)
48{ 50{
49 struct perf_header *self = malloc(sizeof(*self)); 51 struct perf_header *self = calloc(sizeof(*self), 1);
50 52
51 if (!self) 53 if (!self)
52 die("nomem"); 54 die("nomem");
53 55
54 self->frozen = 0;
55
56 self->attrs = 0;
57 self->size = 1; 56 self->size = 1;
58 self->attr = malloc(sizeof(void *)); 57 self->attr = malloc(sizeof(void *));
59 58
60 if (!self->attr) 59 if (!self->attr)
61 die("nomem"); 60 die("nomem");
62 61
63 self->data_offset = 0;
64 self->data_size = 0;
65
66 return self; 62 return self;
67} 63}
68 64
@@ -97,7 +93,7 @@ static struct perf_trace_event_type *events;
97void perf_header__push_event(u64 id, const char *name) 93void perf_header__push_event(u64 id, const char *name)
98{ 94{
99 if (strlen(name) > MAX_EVENT_NAME) 95 if (strlen(name) > MAX_EVENT_NAME)
100 printf("Event %s will be truncated\n", name); 96 pr_warning("Event %s will be truncated\n", name);
101 97
102 if (!events) { 98 if (!events) {
103 events = malloc(sizeof(struct perf_trace_event_type)); 99 events = malloc(sizeof(struct perf_trace_event_type));
@@ -145,8 +141,14 @@ struct perf_file_header {
145 struct perf_file_section attrs; 141 struct perf_file_section attrs;
146 struct perf_file_section data; 142 struct perf_file_section data;
147 struct perf_file_section event_types; 143 struct perf_file_section event_types;
144 DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
148}; 145};
149 146
147void perf_header__feat_trace_info(struct perf_header *header)
148{
149 set_bit(HEADER_TRACE_INFO, header->adds_features);
150}
151
150static void do_write(int fd, void *buf, size_t size) 152static void do_write(int fd, void *buf, size_t size)
151{ 153{
152 while (size) { 154 while (size) {
@@ -160,6 +162,32 @@ static void do_write(int fd, void *buf, size_t size)
160 } 162 }
161} 163}
162 164
165static void perf_header__adds_write(struct perf_header *self, int fd)
166{
167 struct perf_file_section trace_sec;
168 u64 cur_offset = lseek(fd, 0, SEEK_CUR);
169 unsigned long *feat_mask = self->adds_features;
170
171 if (test_bit(HEADER_TRACE_INFO, feat_mask)) {
172 /* Write trace info */
173 trace_sec.offset = lseek(fd, sizeof(trace_sec), SEEK_CUR);
174 read_tracing_data(fd, attrs, nr_counters);
175 trace_sec.size = lseek(fd, 0, SEEK_CUR) - trace_sec.offset;
176
177 /* Write trace info headers */
178 lseek(fd, cur_offset, SEEK_SET);
179 do_write(fd, &trace_sec, sizeof(trace_sec));
180
181 /*
182 * Update cur_offset. So that other (future)
183 * features can set their own infos in this place. But if we are
184 * the only feature, at least that seeks to the place the data
185 * should begin.
186 */
187 cur_offset = lseek(fd, trace_sec.offset + trace_sec.size, SEEK_SET);
188 }
189};
190
163void perf_header__write(struct perf_header *self, int fd) 191void perf_header__write(struct perf_header *self, int fd)
164{ 192{
165 struct perf_file_header f_header; 193 struct perf_file_header f_header;
@@ -198,6 +226,7 @@ void perf_header__write(struct perf_header *self, int fd)
198 if (events) 226 if (events)
199 do_write(fd, events, self->event_size); 227 do_write(fd, events, self->event_size);
200 228
229 perf_header__adds_write(self, fd);
201 230
202 self->data_offset = lseek(fd, 0, SEEK_CUR); 231 self->data_offset = lseek(fd, 0, SEEK_CUR);
203 232
@@ -219,6 +248,8 @@ void perf_header__write(struct perf_header *self, int fd)
219 }, 248 },
220 }; 249 };
221 250
251 memcpy(&f_header.adds_features, &self->adds_features, sizeof(self->adds_features));
252
222 lseek(fd, 0, SEEK_SET); 253 lseek(fd, 0, SEEK_SET);
223 do_write(fd, &f_header, sizeof(f_header)); 254 do_write(fd, &f_header, sizeof(f_header));
224 lseek(fd, self->data_offset + self->data_size, SEEK_SET); 255 lseek(fd, self->data_offset + self->data_size, SEEK_SET);
@@ -241,6 +272,20 @@ static void do_read(int fd, void *buf, size_t size)
241 } 272 }
242} 273}
243 274
275static void perf_header__adds_read(struct perf_header *self, int fd)
276{
277 const unsigned long *feat_mask = self->adds_features;
278
279 if (test_bit(HEADER_TRACE_INFO, feat_mask)) {
280 struct perf_file_section trace_sec;
281
282 do_read(fd, &trace_sec, sizeof(trace_sec));
283 lseek(fd, trace_sec.offset, SEEK_SET);
284 trace_report(fd);
285 lseek(fd, trace_sec.offset + trace_sec.size, SEEK_SET);
286 }
287};
288
244struct perf_header *perf_header__read(int fd) 289struct perf_header *perf_header__read(int fd)
245{ 290{
246 struct perf_header *self = perf_header__new(); 291 struct perf_header *self = perf_header__new();
@@ -254,10 +299,16 @@ struct perf_header *perf_header__read(int fd)
254 do_read(fd, &f_header, sizeof(f_header)); 299 do_read(fd, &f_header, sizeof(f_header));
255 300
256 if (f_header.magic != PERF_MAGIC || 301 if (f_header.magic != PERF_MAGIC ||
257 f_header.size != sizeof(f_header) ||
258 f_header.attr_size != sizeof(f_attr)) 302 f_header.attr_size != sizeof(f_attr))
259 die("incompatible file format"); 303 die("incompatible file format");
260 304
305 if (f_header.size != sizeof(f_header)) {
306 /* Support the previous format */
307 if (f_header.size == offsetof(typeof(f_header), adds_features))
308 bitmap_zero(f_header.adds_features, HEADER_FEAT_BITS);
309 else
310 die("incompatible file format");
311 }
261 nr_attrs = f_header.attrs.size / sizeof(f_attr); 312 nr_attrs = f_header.attrs.size / sizeof(f_attr);
262 lseek(fd, f_header.attrs.offset, SEEK_SET); 313 lseek(fd, f_header.attrs.offset, SEEK_SET);
263 314
@@ -290,6 +341,11 @@ struct perf_header *perf_header__read(int fd)
290 do_read(fd, events, f_header.event_types.size); 341 do_read(fd, events, f_header.event_types.size);
291 event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); 342 event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type);
292 } 343 }
344
345 memcpy(&self->adds_features, &f_header.adds_features, sizeof(f_header.adds_features));
346
347 perf_header__adds_read(self, fd);
348
293 self->event_offset = f_header.event_types.offset; 349 self->event_offset = f_header.event_types.offset;
294 self->event_size = f_header.event_types.size; 350 self->event_size = f_header.event_types.size;
295 351