xref: /aosp_15_r20/external/trace-cmd/tracecmd/trace-dump.c (revision 58e6ee5f017f6a8912852c892d18457e4bafb554)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
4  *
5  * Updates:
6  * Copyright (C) 2019, VMware, Tzvetomir Stoyanov <[email protected]>
7  */
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <getopt.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <errno.h>
14 
15 #include "trace-local.h"
16 
17 #define TRACING_STR	"tracing"
18 #define HEAD_PAGE_STR	"header_page"
19 #define HEAD_PAGE_EVENT	"header_event"
20 #define HEAD_OPTIONS	"options  "
21 #define HEAD_LATENCY	"latency  "
22 #define HEAD_FLYRECORD	"flyrecord"
23 
24 #define DUMP_SIZE	1024
25 
26 static struct tep_handle *tep;
27 static unsigned int trace_cpus;
28 static int has_clock;
29 static unsigned long file_version;
30 static bool	read_compress;
31 static struct tracecmd_compression *compress;
32 static char *meta_strings;
33 static int meta_strings_size;
34 
35 enum dump_items {
36 	SUMMARY		= (1 << 0),
37 	HEAD_PAGE	= (1 << 1),
38 	HEAD_EVENT	= (1 << 2),
39 	FTRACE_FORMAT	= (1 << 3),
40 	EVENT_SYSTEMS	= (1 << 4),
41 	EVENT_FORMAT	= (1 << 5),
42 	KALLSYMS	= (1 << 6),
43 	TRACE_PRINTK	= (1 << 7),
44 	CMDLINES	= (1 << 8),
45 	OPTIONS		= (1 << 9),
46 	FLYRECORD	= (1 << 10),
47 	CLOCK		= (1 << 11),
48 	SECTIONS	= (1 << 12),
49 	STRINGS		= (1 << 13),
50 };
51 
52 struct file_section {
53 	int id;
54 	unsigned long long offset;
55 	struct file_section *next;
56 	enum dump_items verbosity;
57 };
58 
59 static struct file_section *sections;
60 
61 enum dump_items verbosity;
62 
63 #define DUMP_CHECK(X) ((X) & verbosity)
64 
65 #define do_print(ids, fmt, ...)					\
66 	do {							\
67 		if (!(ids) || DUMP_CHECK(ids))			\
68 			tracecmd_plog(fmt, ##__VA_ARGS__);	\
69 	} while (0)
70 
read_fd(int fd,char * dst,int len)71 static int read_fd(int fd, char *dst, int len)
72 {
73 	size_t size = 0;
74 	int r;
75 
76 	do {
77 		r = read(fd, dst+size, len);
78 		if (r > 0) {
79 			size += r;
80 			len -= r;
81 		} else
82 			break;
83 	} while (r > 0);
84 
85 	if (len)
86 		return -1;
87 	return size;
88 }
89 
read_compressed(int fd,char * dst,int len)90 static int read_compressed(int fd, char *dst, int len)
91 {
92 
93 	if (read_compress)
94 		return tracecmd_compress_buffer_read(compress, dst, len);
95 
96 	return read_fd(fd, dst, len);
97 }
98 
do_lseek(int fd,int offset,int whence)99 static int do_lseek(int fd, int offset, int whence)
100 {
101 	if (read_compress)
102 		return tracecmd_compress_lseek(compress, offset, whence);
103 
104 	return lseek64(fd, offset, whence);
105 }
106 
read_file_string(int fd,char * dst,int len)107 static int read_file_string(int fd, char *dst, int len)
108 {
109 	size_t size = 0;
110 	int r;
111 
112 	do {
113 		r = read_compressed(fd, dst+size, 1);
114 		if (r > 0) {
115 			size++;
116 			len--;
117 		} else
118 			break;
119 		if (!dst[size - 1])
120 			break;
121 	} while (r > 0 && len);
122 
123 	if (!size || dst[size - 1])
124 		return -1;
125 	return 0;
126 }
127 
read_file_bytes(int fd,char * dst,int len)128 static int read_file_bytes(int fd, char *dst, int len)
129 {
130 	int ret;
131 
132 	ret = read_compressed(fd, dst, len);
133 	return ret < 0 ? ret : 0;
134 }
135 
read_dump_string(int fd,int size,enum dump_items id)136 static void read_dump_string(int fd, int size, enum dump_items id)
137 {
138 	char buf[DUMP_SIZE];
139 	int lsize;
140 
141 	while (size) {
142 		lsize = (size < DUMP_SIZE) ? size : DUMP_SIZE - 1;
143 		if (read_file_bytes(fd, buf, lsize))
144 			die("cannot read %d bytes", lsize);
145 		buf[lsize] = 0;
146 		do_print(id, "%s", buf);
147 		size -= lsize;
148 	}
149 
150 	do_print(id, "\n");
151 }
152 
read_file_number(int fd,void * digit,int size)153 static int read_file_number(int fd, void *digit, int size)
154 {
155 	unsigned long long val;
156 	char buf[8];
157 
158 	if (size > 8)
159 		return -1;
160 
161 	if (read_file_bytes(fd, buf, size))
162 		return -1;
163 
164 	val = tep_read_number(tep, buf, size);
165 	switch (size) {
166 	case 1:
167 		*((char *)digit) = val;
168 		break;
169 	case 2:
170 		*((unsigned short *)digit) = val;
171 		break;
172 	case 4:
173 		*((unsigned int *)digit) = val;
174 		break;
175 	case 8:
176 		*((unsigned long long *)digit) = val;
177 		break;
178 	default:
179 		return -1;
180 	}
181 
182 	return 0;
183 }
184 
get_metadata_string(int offset)185 static const char *get_metadata_string(int offset)
186 {
187 	if (!meta_strings || offset < 0 || meta_strings_size <= offset)
188 		return NULL;
189 
190 	return meta_strings + offset;
191 }
192 
dump_initial_format(int fd)193 static void dump_initial_format(int fd)
194 {
195 	char magic[] = TRACECMD_MAGIC;
196 	char buf[DUMP_SIZE];
197 	int val4;
198 
199 	do_print(SUMMARY, "\t[Initial format]\n");
200 
201 	/* check initial bytes */
202 	if (read_file_bytes(fd, buf, sizeof(magic)))
203 		die("cannot read %zu bytes magic", sizeof(magic));
204 	if (memcmp(buf, magic, sizeof(magic)) != 0)
205 		die("wrong file magic");
206 
207 	/* check initial tracing string */
208 	if (read_file_bytes(fd, buf, strlen(TRACING_STR)))
209 		die("cannot read %zu bytes tracing string", strlen(TRACING_STR));
210 	buf[strlen(TRACING_STR)] = 0;
211 	if (strncmp(buf, TRACING_STR, strlen(TRACING_STR)) != 0)
212 		die("wrong tracing string: %s", buf);
213 
214 	/* get file version */
215 	if (read_file_string(fd, buf, DUMP_SIZE))
216 		die("no version string");
217 
218 	do_print(SUMMARY, "\t\t%s\t[Version]\n", buf);
219 	file_version = strtol(buf, NULL, 10);
220 	if (!file_version && errno)
221 		die("Invalid file version string %s", buf);
222 	if (!tracecmd_is_version_supported(file_version))
223 		die("Unsupported file version %lu", file_version);
224 
225 	/* get file endianness*/
226 	if (read_file_bytes(fd, buf, 1))
227 		die("cannot read file endianness");
228 	do_print(SUMMARY, "\t\t%d\t[%s endian]\n", buf[0], buf[0]?"Big":"Little");
229 
230 	tep_set_file_bigendian(tep, buf[0]);
231 	tep_set_local_bigendian(tep, tracecmd_host_bigendian());
232 
233 	/* get file bytes per long*/
234 	if (read_file_bytes(fd, buf, 1))
235 		die("cannot read file bytes per long");
236 	do_print(SUMMARY, "\t\t%d\t[Bytes in a long]\n", buf[0]);
237 
238 	if (read_file_number(fd, &val4, 4))
239 		die("cannot read file page size");
240 	do_print(SUMMARY, "\t\t%d\t[Page size, bytes]\n", val4);
241 }
242 
dump_compress(int fd)243 static void dump_compress(int fd)
244 {
245 	char zname[DUMP_SIZE];
246 	char zver[DUMP_SIZE];
247 
248 	if (file_version < FILE_VERSION_COMPRESSION)
249 		return;
250 
251 	/* get compression header */
252 	if (read_file_string(fd, zname, DUMP_SIZE))
253 		die("no compression header");
254 
255 	if (read_file_string(fd, zver, DUMP_SIZE))
256 		die("no compression version");
257 
258 	do_print((SUMMARY), "\t\t%s\t[Compression algorithm]\n", zname);
259 	do_print((SUMMARY), "\t\t%s\t[Compression version]\n", zver);
260 
261 	if (strcmp(zname, "none")) {
262 		compress = tracecmd_compress_alloc(zname, zver, fd, tep, NULL);
263 		if (!compress)
264 			die("cannot uncompress the file");
265 	}
266 }
267 
dump_header_page(int fd)268 static void dump_header_page(int fd)
269 {
270 	unsigned long long size;
271 	char buf[DUMP_SIZE];
272 
273 	do_print((SUMMARY | HEAD_PAGE), "\t[Header page, ");
274 
275 	/* check header string */
276 	if (read_file_bytes(fd, buf, strlen(HEAD_PAGE_STR) + 1))
277 		die("cannot read %zu bytes header string", strlen(HEAD_PAGE_STR));
278 	if (strncmp(buf, HEAD_PAGE_STR, strlen(HEAD_PAGE_STR)) != 0)
279 		die("wrong header string: %s", buf);
280 
281 	if (read_file_number(fd, &size, 8))
282 		die("cannot read the size of the page header information");
283 
284 	do_print((SUMMARY | HEAD_PAGE), "%lld bytes]\n", size);
285 
286 	read_dump_string(fd, size, HEAD_PAGE);
287 }
288 
dump_header_event(int fd)289 static void dump_header_event(int fd)
290 {
291 	unsigned long long size;
292 	char buf[DUMP_SIZE];
293 
294 	do_print((SUMMARY | HEAD_EVENT), "\t[Header event, ");
295 
296 	/* check header string */
297 	if (read_file_bytes(fd, buf, strlen(HEAD_PAGE_EVENT) + 1))
298 		die("cannot read %zu bytes header string", strlen(HEAD_PAGE_EVENT));
299 	if (strncmp(buf, HEAD_PAGE_EVENT, strlen(HEAD_PAGE_EVENT)) != 0)
300 		die("wrong header string: %s", buf);
301 
302 	if (read_file_number(fd, &size, 8))
303 		die("cannot read the size of the page header information");
304 
305 	do_print((SUMMARY | HEAD_EVENT), "%lld bytes]\n", size);
306 
307 	read_dump_string(fd, size, HEAD_EVENT);
308 }
309 
uncompress_reset(void)310 static void uncompress_reset(void)
311 {
312 	if (compress && file_version >= FILE_VERSION_COMPRESSION) {
313 		read_compress = false;
314 		tracecmd_compress_reset(compress);
315 	}
316 }
317 
uncompress_block(void)318 static int uncompress_block(void)
319 {
320 	int ret = 0;
321 
322 	if (compress && file_version >= FILE_VERSION_COMPRESSION) {
323 		ret = tracecmd_uncompress_block(compress);
324 		if (!ret)
325 			read_compress = true;
326 
327 	}
328 
329 	return ret;
330 }
331 
dump_ftrace_events_format(int fd)332 static void dump_ftrace_events_format(int fd)
333 {
334 	unsigned long long size;
335 	unsigned int count;
336 
337 	do_print((SUMMARY | FTRACE_FORMAT), "\t[Ftrace format, ");
338 	if (read_file_number(fd, &count, 4))
339 		die("cannot read the count of the ftrace events");
340 
341 	do_print((SUMMARY | FTRACE_FORMAT), "%d events]\n", count);
342 
343 	while (count) {
344 		if (read_file_number(fd, &size, 8))
345 			die("cannot read the size of the %d ftrace event", count);
346 		read_dump_string(fd, size, FTRACE_FORMAT);
347 		count--;
348 	}
349 }
350 
dump_events_format(int fd)351 static void dump_events_format(int fd)
352 {
353 	unsigned long long size;
354 	unsigned int systems;
355 	unsigned int events;
356 	char buf[DUMP_SIZE];
357 
358 	do_print((SUMMARY | EVENT_FORMAT | EVENT_SYSTEMS), "\t[Events format, ");
359 
360 	if (read_file_number(fd, &systems, 4))
361 		die("cannot read the count of the event systems");
362 
363 	do_print((SUMMARY | EVENT_FORMAT | EVENT_SYSTEMS), "%d systems]\n", systems);
364 
365 	while (systems) {
366 
367 		if (read_file_string(fd, buf, DUMP_SIZE))
368 			die("cannot read the name of the %dth system", systems);
369 		if (read_file_number(fd, &events, 4))
370 			die("cannot read the count of the events in system %s",
371 			     buf);
372 		do_print(EVENT_SYSTEMS, "\t\t%s %d [system, events]\n", buf, events);
373 		while (events) {
374 			if (read_file_number(fd, &size, 8))
375 				die("cannot read the format size of the %dth event from system %s",
376 				    events, buf);
377 			read_dump_string(fd, size, EVENT_FORMAT);
378 			events--;
379 		}
380 		systems--;
381 	}
382 }
383 
dump_kallsyms(int fd)384 static void dump_kallsyms(int fd)
385 {
386 	unsigned int size;
387 
388 	do_print((SUMMARY | KALLSYMS), "\t[Kallsyms, ");
389 
390 	if (read_file_number(fd, &size, 4))
391 		die("cannot read the size of the kallsyms");
392 
393 	do_print((SUMMARY | KALLSYMS), "%d bytes]\n", size);
394 
395 	read_dump_string(fd, size, KALLSYMS);
396 }
397 
dump_printk(int fd)398 static void dump_printk(int fd)
399 {
400 	unsigned int size;
401 
402 	do_print((SUMMARY | TRACE_PRINTK), "\t[Trace printk, ");
403 
404 	if (read_file_number(fd, &size, 4))
405 		die("cannot read the size of the trace printk");
406 
407 	do_print((SUMMARY | TRACE_PRINTK), "%d bytes]\n", size);
408 
409 	read_dump_string(fd, size, TRACE_PRINTK);
410 }
411 
dump_cmdlines(int fd)412 static void dump_cmdlines(int fd)
413 {
414 	unsigned long long size;
415 
416 	do_print((SUMMARY | CMDLINES), "\t[Saved command lines, ");
417 
418 	if (read_file_number(fd, &size, 8))
419 		die("cannot read the size of the saved command lines");
420 
421 	do_print((SUMMARY | CMDLINES), "%d bytes]\n", size);
422 
423 	read_dump_string(fd, size, CMDLINES);
424 }
425 
dump_cpus_count(int fd)426 static void dump_cpus_count(int fd)
427 {
428 	if (read_file_number(fd, &trace_cpus, 4))
429 		die("cannot read the cpu count");
430 
431 	do_print(SUMMARY, "\t%d [CPUs with tracing data]\n", trace_cpus);
432 }
433 
dump_option_string(int fd,int size,char * desc)434 static void dump_option_string(int fd, int size, char *desc)
435 {
436 	do_print(OPTIONS, "\t\t[Option %s, %d bytes]\n", desc, size);
437 	if (size)
438 		read_dump_string(fd, size, OPTIONS);
439 }
440 
dump_section_header(int fd,enum dump_items v,unsigned short * flags)441 static void dump_section_header(int fd, enum dump_items v, unsigned short *flags)
442 {
443 	unsigned long long offset, size;
444 	unsigned short fl;
445 	unsigned short id;
446 	const char *desc;
447 	int desc_id;
448 
449 	offset = lseek64(fd, 0, SEEK_CUR);
450 	if (read_file_number(fd, &id, 2))
451 		die("cannot read the section id");
452 
453 	if (read_file_number(fd, &fl, 2))
454 		die("cannot read the section flags");
455 
456 	if (read_file_number(fd, &desc_id, 4))
457 		die("no section description");
458 
459 	desc = get_metadata_string(desc_id);
460 	if (!desc)
461 		desc = "Unknown";
462 
463 	if (read_file_number(fd, &size, 8))
464 		die("cannot read section size");
465 
466 	do_print(v, "\t[Section %d @ %lld: \"%s\", flags 0x%X, %lld bytes]\n",
467 		 id, offset, desc, fl, size);
468 
469 	if (flags)
470 		*flags = fl;
471 }
472 
dump_option_buffer(int fd,unsigned short option,int size)473 static void dump_option_buffer(int fd, unsigned short option, int size)
474 {
475 	unsigned long long total_size = 0;
476 	unsigned long long data_size;
477 	unsigned long long current;
478 	unsigned long long offset;
479 	unsigned short flags;
480 	char clock[DUMP_SIZE];
481 	char name[DUMP_SIZE];
482 	int page_size;
483 	int cpus = 0;
484 	int id;
485 	int i;
486 
487 	if (size < 8)
488 		die("broken buffer option with size %d", size);
489 
490 	if (read_file_number(fd, &offset, 8))
491 		die("cannot read the offset of the buffer option");
492 
493 	if (read_file_string(fd, name, DUMP_SIZE))
494 		die("cannot read the name of the buffer option");
495 
496 	if (file_version < FILE_VERSION_SECTIONS) {
497 		do_print(OPTIONS|FLYRECORD, "\t\t[Option BUFFER, %d bytes]\n", size);
498 		do_print(OPTIONS|FLYRECORD, "%lld [offset]\n", offset);
499 		do_print(OPTIONS|FLYRECORD, "\"%s\" [name]\n", name);
500 		return;
501 	}
502 
503 	current = lseek64(fd, 0, SEEK_CUR);
504 	if (lseek64(fd, offset, SEEK_SET) == (off_t)-1)
505 		die("cannot goto buffer offset %lld", offset);
506 
507 	dump_section_header(fd, FLYRECORD, &flags);
508 
509 	if (lseek64(fd, current, SEEK_SET) == (off_t)-1)
510 		die("cannot go back to buffer option");
511 
512 	do_print(OPTIONS|FLYRECORD, "\t\t[Option BUFFER, %d bytes]\n", size);
513 	do_print(OPTIONS|FLYRECORD, "%lld [offset]\n", offset);
514 	do_print(OPTIONS|FLYRECORD, "\"%s\" [name]\n", name);
515 
516 	if (read_file_string(fd, clock, DUMP_SIZE))
517 		die("cannot read clock of the buffer option");
518 
519 	do_print(OPTIONS|FLYRECORD, "\"%s\" [clock]\n", clock);
520 	if (option == TRACECMD_OPTION_BUFFER) {
521 		if (read_file_number(fd, &page_size, 4))
522 			die("cannot read the page size of the buffer option");
523 		do_print(OPTIONS|FLYRECORD, "%d [Page size, bytes]\n", page_size);
524 
525 		if (read_file_number(fd, &cpus, 4))
526 			die("cannot read the cpu count of the buffer option");
527 
528 		do_print(OPTIONS|FLYRECORD, "%d [CPUs]:\n", cpus);
529 		for (i = 0; i < cpus; i++) {
530 			if (read_file_number(fd, &id, 4))
531 				die("cannot read the id of cpu %d from the buffer option", i);
532 
533 			if (read_file_number(fd, &offset, 8))
534 				die("cannot read the offset of cpu %d from the buffer option", i);
535 
536 			if (read_file_number(fd, &data_size, 8))
537 				die("cannot read the data size of cpu %d from the buffer option", i);
538 
539 			total_size += data_size;
540 			do_print(OPTIONS|FLYRECORD, "   %d %lld\t%lld\t[id, data offset and size]\n",
541 				 id, offset, data_size);
542 		}
543 		do_print(SUMMARY, "\t\[buffer \"%s\", \"%s\" clock, %d page size, "
544 			 "%d cpus, %lld bytes flyrecord data]\n",
545 			 name, clock, page_size, cpus, total_size);
546 	} else {
547 		do_print(SUMMARY, "\t\[buffer \"%s\", \"%s\" clock, latency data]\n", name, clock);
548 	}
549 
550 }
551 
dump_option_int(int fd,int size,char * desc)552 static void dump_option_int(int fd, int size, char *desc)
553 {
554 	int val;
555 
556 	do_print(OPTIONS, "\t\t[Option %s, %d bytes]\n", desc, size);
557 	read_file_number(fd, &val, size);
558 	do_print(OPTIONS, "%d\n", val);
559 }
560 
dump_option_xlong(int fd,int size,char * desc)561 static void dump_option_xlong(int fd, int size, char *desc)
562 {
563 	long long val;
564 
565 	do_print(OPTIONS, "\t\t[Option %s, %d bytes]\n", desc, size);
566 	read_file_number(fd, &val, size);
567 	do_print(OPTIONS, "0x%llX\n", val);
568 }
569 
570 struct time_shift_cpu {
571 	unsigned int count;
572 	long long *scalings;
573 	long long *frac;
574 	long long *offsets;
575 	unsigned long long *times;
576 };
577 
dump_option_timeshift(int fd,int size)578 static void dump_option_timeshift(int fd, int size)
579 {
580 	struct time_shift_cpu *cpus_data;
581 	long long trace_id;
582 	unsigned int flags;
583 	unsigned int cpus;
584 	int i, j;
585 
586 	/*
587 	 * long long int (8 bytes) trace session ID
588 	 * int (4 bytes) count of timestamp offsets.
589 	 * long long array of size [count] of times,
590 	 *      when the offsets were calculated.
591 	 * long long array of size [count] of timestamp offsets.
592 	 */
593 	if (size < 12) {
594 		do_print(OPTIONS, "Broken time shift option, size %s", size);
595 		return;
596 	}
597 	do_print(OPTIONS, "\t\t[Option TimeShift, %d bytes]\n", size);
598 	read_file_number(fd, &trace_id, 8);
599 	size -= 8;
600 	do_print(OPTIONS, "0x%llX [peer's trace id]\n", trace_id);
601 	read_file_number(fd, &flags, 4);
602 	size -= 4;
603 	do_print(OPTIONS, "0x%llX [peer's protocol flags]\n", flags);
604 	read_file_number(fd, &cpus, 4);
605 	size -= 4;
606 	do_print(OPTIONS, "0x%llX [peer's CPU count]\n", cpus);
607 	cpus_data = calloc(cpus, sizeof(struct time_shift_cpu));
608 	if (!cpus_data)
609 		return;
610 	for (j = 0; j < cpus; j++) {
611 		if (size < 4)
612 			goto out;
613 		read_file_number(fd, &cpus_data[j].count, 4);
614 		size -= 4;
615 		do_print(OPTIONS, "%lld [samples count for CPU %d]\n", cpus_data[j].count, j);
616 		cpus_data[j].times = calloc(cpus_data[j].count, sizeof(long long));
617 		cpus_data[j].offsets = calloc(cpus_data[j].count, sizeof(long long));
618 		cpus_data[j].scalings = calloc(cpus_data[j].count, sizeof(long long));
619 		cpus_data[j].frac = calloc(cpus_data[j].count, sizeof(long long));
620 		if (!cpus_data[j].times || !cpus_data[j].offsets ||
621 		    !cpus_data[j].scalings || !cpus_data[j].frac)
622 			goto out;
623 		for (i = 0; i < cpus_data[j].count; i++) {
624 			if (size < 8)
625 				goto out;
626 			read_file_number(fd, cpus_data[j].times + i, 8);
627 			size -= 8;
628 		}
629 		for (i = 0; i < cpus_data[j].count; i++) {
630 			if (size < 8)
631 				goto out;
632 			read_file_number(fd, cpus_data[j].offsets + i, 8);
633 			size -= 8;
634 		}
635 		for (i = 0; i < cpus_data[j].count; i++) {
636 			if (size < 8)
637 				goto out;
638 			read_file_number(fd, cpus_data[j].scalings + i, 8);
639 			size -= 8;
640 		}
641 	}
642 
643 	if (size > 0) {
644 		for (j = 0; j < cpus; j++) {
645 			if (!cpus_data[j].frac)
646 				goto out;
647 			for (i = 0; i < cpus_data[j].count; i++) {
648 				if (size < 8)
649 					goto out;
650 				read_file_number(fd, cpus_data[j].frac + i, 8);
651 				size -= 8;
652 			}
653 		}
654 	}
655 
656 	for (j = 0; j < cpus; j++) {
657 		for (i = 0; i < cpus_data[j].count; i++)
658 			do_print(OPTIONS, "\t%lld %lld %llu %llu[offset * scaling >> fraction @ time]\n",
659 				 cpus_data[j].offsets[i], cpus_data[j].scalings[i],
660 				 cpus_data[j].frac[i], cpus_data[j].times[i]);
661 
662 	}
663 
664 out:
665 	if (j < cpus)
666 		do_print(OPTIONS, "Broken time shift option\n");
667 	for (j = 0; j < cpus; j++) {
668 		free(cpus_data[j].times);
669 		free(cpus_data[j].offsets);
670 		free(cpus_data[j].scalings);
671 		free(cpus_data[j].frac);
672 	}
673 	free(cpus_data);
674 }
675 
dump_option_guest(int fd,int size)676 void dump_option_guest(int fd, int size)
677 {
678 	unsigned long long trace_id;
679 	char *buf, *p;
680 	int cpu, pid;
681 	int cpus;
682 	int i;
683 
684 	do_print(OPTIONS, "\t\t[Option GUEST, %d bytes]\n", size);
685 
686 	/*
687 	 * Guest name, null terminated string
688 	 * long long (8 bytes) trace-id
689 	 * int (4 bytes) number of guest CPUs
690 	 * array of size number of guest CPUs:
691 	 *	int (4 bytes) Guest CPU id
692 	 *	int (4 bytes) Host PID, running the guest CPU
693 	 */
694 	buf = calloc(1, size);
695 	if (!buf)
696 		return;
697 	if (read_file_bytes(fd, buf, size))
698 		goto out;
699 
700 	p = buf;
701 	do_print(OPTIONS, "%s [Guest name]\n", p);
702 	size -= strlen(buf) + 1;
703 	p += strlen(buf) + 1;
704 
705 	if (size < sizeof(long long))
706 		goto out;
707 	trace_id = tep_read_number(tep, p, sizeof(long long));
708 	size -= sizeof(long long);
709 	p += sizeof(long long);
710 	do_print(OPTIONS, "0x%llX [trace id]\n", trace_id);
711 
712 	if (size < sizeof(int))
713 		goto out;
714 	cpus = tep_read_number(tep, p, sizeof(int));
715 	size -= sizeof(int);
716 	p += sizeof(int);
717 	do_print(OPTIONS, "%d [Guest CPUs]\n", cpus);
718 
719 	for (i = 0; i < cpus; i++) {
720 		if (size < 2 * sizeof(int))
721 			goto out;
722 		cpu = tep_read_number(tep, p, sizeof(int));
723 		size -= sizeof(int);
724 		p += sizeof(int);
725 		pid = tep_read_number(tep, p, sizeof(int));
726 		size -= sizeof(int);
727 		p += sizeof(int);
728 		do_print(OPTIONS, "  %d %d [guest cpu, host pid]\n", cpu, pid);
729 	}
730 
731 out:
732 	free(buf);
733 }
734 
dump_option_tsc2nsec(int fd,int size)735 void dump_option_tsc2nsec(int fd, int size)
736 {
737 	int mult, shift;
738 	unsigned long long offset;
739 
740 	do_print(OPTIONS, "\n\t\t[Option TSC2NSEC, %d bytes]\n", size);
741 
742 	if (read_file_number(fd, &mult, 4))
743 		die("cannot read tsc2nsec multiplier");
744 	if (read_file_number(fd, &shift, 4))
745 		die("cannot read tsc2nsec shift");
746 	if (read_file_number(fd, &offset, 8))
747 		die("cannot read tsc2nsec offset");
748 	do_print(OPTIONS, "%d %d %llu [multiplier, shift, offset]\n", mult, shift, offset);
749 }
750 
dump_option_section(int fd,unsigned int size,unsigned short id,char * desc,enum dump_items v)751 static void dump_option_section(int fd, unsigned int size,
752 				unsigned short id, char *desc, enum dump_items v)
753 {
754 	struct file_section *sec;
755 
756 	sec = calloc(1, sizeof(struct file_section));
757 	if (!sec)
758 		die("cannot allocate new section");
759 
760 	sec->next = sections;
761 	sections = sec;
762 	sec->id = id;
763 	sec->verbosity = v;
764 	if (read_file_number(fd, &sec->offset, 8))
765 		die("cannot read the option %d offset", id);
766 
767 	do_print(OPTIONS, "\t\t[Option %s, %d bytes] @ %lld\n", desc, size, sec->offset);
768 }
769 
dump_sections(int fd,int count)770 static void dump_sections(int fd, int count)
771 {
772 	struct file_section *sec = sections;
773 	unsigned short flags;
774 
775 	while (sec) {
776 		if (lseek64(fd, sec->offset, SEEK_SET) == (off_t)-1)
777 			die("cannot goto option offset %lld", sec->offset);
778 
779 		dump_section_header(fd, sec->verbosity, &flags);
780 
781 		if ((flags & TRACECMD_SEC_FL_COMPRESS) && uncompress_block())
782 			die("cannot uncompress section block");
783 
784 		switch (sec->id) {
785 		case TRACECMD_OPTION_HEADER_INFO:
786 			dump_header_page(fd);
787 			dump_header_event(fd);
788 			break;
789 		case TRACECMD_OPTION_FTRACE_EVENTS:
790 			dump_ftrace_events_format(fd);
791 			break;
792 		case TRACECMD_OPTION_EVENT_FORMATS:
793 			dump_events_format(fd);
794 			break;
795 		case TRACECMD_OPTION_KALLSYMS:
796 			dump_kallsyms(fd);
797 			break;
798 		case TRACECMD_OPTION_PRINTK:
799 			dump_printk(fd);
800 			break;
801 		case TRACECMD_OPTION_CMDLINES:
802 			dump_cmdlines(fd);
803 			break;
804 		}
805 		uncompress_reset();
806 		sec = sec->next;
807 	}
808 	do_print(SUMMARY|SECTIONS, "\t[%d sections]\n", count);
809 }
810 
811 static int dump_options_read(int fd);
812 
dump_option_done(int fd,int size)813 static int dump_option_done(int fd, int size)
814 {
815 	unsigned long long offset;
816 
817 	do_print(OPTIONS, "\t\t[Option DONE, %d bytes]\n", size);
818 
819 	if (file_version < FILE_VERSION_SECTIONS || size < 8)
820 		return 0;
821 
822 	if (read_file_number(fd, &offset, 8))
823 		die("cannot read the next options offset");
824 
825 	do_print(OPTIONS, "%lld\n", offset);
826 	if (!offset)
827 		return 0;
828 
829 	if (lseek64(fd, offset, SEEK_SET) == (off_t)-1)
830 		die("cannot goto next options offset %lld", offset);
831 
832 	do_print(OPTIONS, "\n\n");
833 
834 	return dump_options_read(fd);
835 }
836 
dump_options_read(int fd)837 static int dump_options_read(int fd)
838 {
839 	unsigned short flags = 0;
840 	unsigned short option;
841 	unsigned int size;
842 	int count = 0;
843 
844 	if (file_version >= FILE_VERSION_SECTIONS)
845 		dump_section_header(fd, OPTIONS, &flags);
846 
847 	if ((flags & TRACECMD_SEC_FL_COMPRESS) && uncompress_block())
848 		die("cannot uncompress file block");
849 
850 	for (;;) {
851 		if (read_file_number(fd, &option, 2))
852 			die("cannot read the option id");
853 		if (option == TRACECMD_OPTION_DONE && file_version < FILE_VERSION_SECTIONS)
854 			break;
855 		if (read_file_number(fd, &size, 4))
856 			die("cannot read the option size");
857 
858 		count++;
859 		switch (option) {
860 		case TRACECMD_OPTION_DATE:
861 			dump_option_string(fd, size, "DATE");
862 			break;
863 		case TRACECMD_OPTION_CPUSTAT:
864 			dump_option_string(fd, size, "CPUSTAT");
865 			break;
866 		case TRACECMD_OPTION_BUFFER:
867 		case TRACECMD_OPTION_BUFFER_TEXT:
868 			dump_option_buffer(fd, option, size);
869 			break;
870 		case TRACECMD_OPTION_TRACECLOCK:
871 			do_print(OPTIONS, "\t\t[Option TRACECLOCK, %d bytes]\n", size);
872 			read_dump_string(fd, size, OPTIONS | CLOCK);
873 			has_clock = 1;
874 			break;
875 		case TRACECMD_OPTION_UNAME:
876 			dump_option_string(fd, size, "UNAME");
877 			break;
878 		case TRACECMD_OPTION_HOOK:
879 			dump_option_string(fd, size, "HOOK");
880 			break;
881 		case TRACECMD_OPTION_OFFSET:
882 			dump_option_string(fd, size, "OFFSET");
883 			break;
884 		case TRACECMD_OPTION_CPUCOUNT:
885 			dump_option_int(fd, size, "CPUCOUNT");
886 			break;
887 		case TRACECMD_OPTION_VERSION:
888 			dump_option_string(fd, size, "VERSION");
889 			break;
890 		case TRACECMD_OPTION_PROCMAPS:
891 			dump_option_string(fd, size, "PROCMAPS");
892 			break;
893 		case TRACECMD_OPTION_TRACEID:
894 			dump_option_xlong(fd, size, "TRACEID");
895 			break;
896 		case TRACECMD_OPTION_TIME_SHIFT:
897 			dump_option_timeshift(fd, size);
898 			break;
899 		case TRACECMD_OPTION_GUEST:
900 			dump_option_guest(fd, size);
901 			break;
902 		case TRACECMD_OPTION_TSC2NSEC:
903 			dump_option_tsc2nsec(fd, size);
904 			break;
905 		case TRACECMD_OPTION_HEADER_INFO:
906 			dump_option_section(fd, size, option, "HEADERS", HEAD_PAGE | HEAD_EVENT);
907 			break;
908 		case TRACECMD_OPTION_FTRACE_EVENTS:
909 			dump_option_section(fd, size, option, "FTRACE EVENTS", FTRACE_FORMAT);
910 			break;
911 		case TRACECMD_OPTION_EVENT_FORMATS:
912 			dump_option_section(fd, size, option,
913 					    "EVENT FORMATS", EVENT_SYSTEMS | EVENT_FORMAT);
914 			break;
915 		case TRACECMD_OPTION_KALLSYMS:
916 			dump_option_section(fd, size, option, "KALLSYMS", KALLSYMS);
917 			break;
918 		case TRACECMD_OPTION_PRINTK:
919 			dump_option_section(fd, size, option, "PRINTK", TRACE_PRINTK);
920 			break;
921 		case TRACECMD_OPTION_CMDLINES:
922 			dump_option_section(fd, size, option, "CMDLINES", CMDLINES);
923 			break;
924 		case TRACECMD_OPTION_DONE:
925 			uncompress_reset();
926 			count += dump_option_done(fd, size);
927 			return count;
928 		default:
929 			do_print(OPTIONS, " %d %d\t[Unknown option, size - skipping]\n",
930 				 option, size);
931 			do_lseek(fd, size, SEEK_CUR);
932 			break;
933 		}
934 	}
935 	uncompress_reset();
936 	return count;
937 }
938 
dump_options(int fd)939 static void dump_options(int fd)
940 {
941 	int count;
942 
943 	count = dump_options_read(fd);
944 	do_print(SUMMARY|OPTIONS, "\t[%d options]\n", count);
945 }
946 
dump_latency(int fd)947 static void dump_latency(int fd)
948 {
949 	do_print(SUMMARY, "\t[Latency tracing data]\n");
950 }
951 
dump_clock(int fd)952 static void dump_clock(int fd)
953 {
954 	long long size;
955 	char *clock;
956 
957 	do_print((SUMMARY | CLOCK), "\t[Tracing clock]\n");
958 	if (!has_clock) {
959 		do_print((SUMMARY | CLOCK), "\t\t No tracing clock saved in the file\n");
960 		return;
961 	}
962 	if (read_file_number(fd, &size, 8))
963 		die("cannot read clock size");
964 	clock = calloc(1, size);
965 	if (!clock)
966 		die("cannot allocate clock %lld bytes", size);
967 
968 	if (read_file_bytes(fd, clock, size))
969 		die("cannot read clock %lld bytes", size);
970 	clock[size] = 0;
971 	do_print((SUMMARY | CLOCK), "\t\t%s\n", clock);
972 	free(clock);
973 }
974 
dump_flyrecord(int fd)975 static void dump_flyrecord(int fd)
976 {
977 	long long cpu_offset;
978 	long long cpu_size;
979 	int i;
980 
981 	do_print((SUMMARY | FLYRECORD), "\t[Flyrecord tracing data]\n");
982 
983 	for (i = 0; i < trace_cpus; i++) {
984 		if (read_file_number(fd, &cpu_offset, 8))
985 			die("cannot read the cpu %d offset", i);
986 		if (read_file_number(fd, &cpu_size, 8))
987 			die("cannot read the cpu %d size", i);
988 		do_print(FLYRECORD, "\t %10.lld %10.lld\t[offset, size of cpu %d]\n",
989 			 cpu_offset, cpu_size, i);
990 	}
991 	dump_clock(fd);
992 }
993 
dump_therest(int fd)994 static void dump_therest(int fd)
995 {
996 	char str[10];
997 
998 	for (;;) {
999 		if (read_file_bytes(fd, str, 10))
1000 			die("cannot read the rest of the header");
1001 
1002 		if (strncmp(str, HEAD_OPTIONS, 10) == 0)
1003 			dump_options(fd);
1004 		else if (strncmp(str, HEAD_LATENCY, 10) == 0)
1005 			dump_latency(fd);
1006 		else if (strncmp(str, HEAD_FLYRECORD, 10) == 0)
1007 			dump_flyrecord(fd);
1008 		else {
1009 			lseek64(fd, -10, SEEK_CUR);
1010 			break;
1011 		}
1012 	}
1013 }
1014 
dump_v6_file(int fd)1015 static void dump_v6_file(int fd)
1016 {
1017 	dump_header_page(fd);
1018 	dump_header_event(fd);
1019 	dump_ftrace_events_format(fd);
1020 	dump_events_format(fd);
1021 	dump_kallsyms(fd);
1022 	dump_printk(fd);
1023 	dump_cmdlines(fd);
1024 	dump_cpus_count(fd);
1025 	dump_therest(fd);
1026 }
1027 
read_metadata_strings(int fd,unsigned long long size)1028 static int read_metadata_strings(int fd, unsigned long long size)
1029 {
1030 	char *str, *strings;
1031 	int psize;
1032 	int ret;
1033 
1034 	strings = realloc(meta_strings, meta_strings_size + size);
1035 	if (!strings)
1036 		return -1;
1037 	meta_strings = strings;
1038 
1039 	ret = read_file_bytes(fd, meta_strings + meta_strings_size, size);
1040 	if (ret < 0)
1041 		return -1;
1042 
1043 	do_print(STRINGS, "\t[String @ offset]\n");
1044 	psize = 0;
1045 	while (psize < size) {
1046 		str = meta_strings + meta_strings_size + psize;
1047 		do_print(STRINGS, "\t\t\"%s\" @ %d\n", str, meta_strings_size + psize);
1048 		psize += strlen(str) + 1;
1049 	}
1050 
1051 	meta_strings_size += size;
1052 
1053 	return 0;
1054 }
1055 
get_meta_strings(int fd)1056 static void get_meta_strings(int fd)
1057 {
1058 	unsigned long long offset, size;
1059 	unsigned int csize, rsize;
1060 	unsigned short fl, id;
1061 	int desc_id;
1062 
1063 	offset = lseek64(fd, 0, SEEK_CUR);
1064 	do {
1065 		if (read_file_number(fd, &id, 2))
1066 			break;
1067 		if (read_file_number(fd, &fl, 2))
1068 			die("cannot read section flags");
1069 		if (read_file_number(fd, &desc_id, 4))
1070 			die("cannot read section description");
1071 		if (read_file_number(fd, &size, 8))
1072 			die("cannot read section size");
1073 		if (id == TRACECMD_OPTION_STRINGS) {
1074 			if ((fl & TRACECMD_SEC_FL_COMPRESS)) {
1075 				read_file_number(fd, &csize, 4);
1076 				read_file_number(fd, &rsize, 4);
1077 				lseek64(fd, -8, SEEK_CUR);
1078 				if (uncompress_block())
1079 					break;
1080 			} else {
1081 				rsize = size;
1082 			}
1083 			read_metadata_strings(fd, rsize);
1084 			uncompress_reset();
1085 		} else {
1086 			if (lseek64(fd, size, SEEK_CUR) == (off_t)-1)
1087 				break;
1088 		}
1089 	} while (1);
1090 
1091 	if (lseek64(fd, offset, SEEK_SET) == (off_t)-1)
1092 		die("cannot restore the original file location");
1093 }
1094 
walk_v7_sections(int fd)1095 static int walk_v7_sections(int fd)
1096 {
1097 	unsigned long long offset, soffset, size;
1098 	unsigned short fl;
1099 	unsigned short id;
1100 	int csize, rsize;
1101 	int count = 0;
1102 	int desc_id;
1103 	const char *desc;
1104 
1105 	offset = lseek64(fd, 0, SEEK_CUR);
1106 	do {
1107 		soffset = lseek64(fd, 0, SEEK_CUR);
1108 		if (read_file_number(fd, &id, 2))
1109 			break;
1110 
1111 		if (read_file_number(fd, &fl, 2))
1112 			die("cannot read section flags");
1113 
1114 		if (read_file_number(fd, &desc_id, 4))
1115 			die("cannot read section description");
1116 
1117 		desc = get_metadata_string(desc_id);
1118 		if (!desc)
1119 			desc = "Unknown";
1120 
1121 		if (read_file_number(fd, &size, 8))
1122 			die("cannot read section size");
1123 
1124 		if (id >= TRACECMD_OPTION_MAX)
1125 			do_print(SECTIONS, "Unknown section id %d: %s", id, desc);
1126 
1127 		count++;
1128 		if (fl & TRACECMD_SEC_FL_COMPRESS) {
1129 			if (id == TRACECMD_OPTION_BUFFER ||
1130 			    id == TRACECMD_OPTION_BUFFER_TEXT) {
1131 				do_print(SECTIONS,
1132 					"\t[Section %2d @ %-16lld\t\"%s\", flags 0x%X, "
1133 					"%lld compressed bytes]\n",
1134 					 id, soffset, desc, fl, size);
1135 			} else {
1136 				if (read_file_number(fd, &csize, 4))
1137 					die("cannot read section size");
1138 
1139 				if (read_file_number(fd, &rsize, 4))
1140 					die("cannot read section size");
1141 
1142 				do_print(SECTIONS, "\t[Section %2d @ %-16lld\t\"%s\", flags 0x%X, "
1143 					 "%d compressed, %d uncompressed]\n",
1144 					 id, soffset, desc, fl, csize, rsize);
1145 				size -= 8;
1146 			}
1147 		} else {
1148 			do_print(SECTIONS, "\t[Section %2d @ %-16lld\t\"%s\", flags 0x%X, %lld bytes]\n",
1149 				 id, soffset, desc, fl, size);
1150 		}
1151 
1152 		if (lseek64(fd, size, SEEK_CUR) == (off_t)-1)
1153 			break;
1154 	} while (1);
1155 
1156 	if (lseek64(fd, offset, SEEK_SET) == (off_t)-1)
1157 		die("cannot restore the original file location");
1158 
1159 	return count;
1160 }
1161 
dump_v7_file(int fd)1162 static void dump_v7_file(int fd)
1163 {
1164 	long long offset;
1165 	int sections;
1166 
1167 	if (read_file_number(fd, &offset, 8))
1168 		die("cannot read offset of the first option section");
1169 
1170 	get_meta_strings(fd);
1171 	sections = walk_v7_sections(fd);
1172 
1173 	if (lseek64(fd, offset, SEEK_SET) == (off_t)-1)
1174 		die("cannot goto options offset %lld", offset);
1175 
1176 	dump_options(fd);
1177 	dump_sections(fd, sections);
1178 }
1179 
free_sections(void)1180 static void free_sections(void)
1181 {
1182 	struct file_section *del;
1183 
1184 	while (sections) {
1185 		del = sections;
1186 		sections = sections->next;
1187 		free(del);
1188 	}
1189 }
1190 
dump_file(const char * file)1191 static void dump_file(const char *file)
1192 {
1193 	int fd;
1194 
1195 	tep = tep_alloc();
1196 	if (!tep)
1197 		return;
1198 
1199 	fd = open(file, O_RDONLY);
1200 	if (fd < 0)
1201 		die("cannot open '%s'\n", file);
1202 
1203 	do_print(SUMMARY, "\n Tracing meta data in file %s:\n", file);
1204 
1205 	dump_initial_format(fd);
1206 	dump_compress(fd);
1207 	if (file_version < FILE_VERSION_SECTIONS)
1208 		dump_v6_file(fd);
1209 	else
1210 		dump_v7_file(fd);
1211 	free_sections();
1212 	tep_free(tep);
1213 	tep = NULL;
1214 	close(fd);
1215 }
1216 
1217 enum {
1218 	OPT_sections	= 240,
1219 	OPT_strings	= 241,
1220 	OPT_verbose	= 242,
1221 	OPT_clock	= 243,
1222 	OPT_all		= 244,
1223 	OPT_summary	= 245,
1224 	OPT_flyrecord	= 246,
1225 	OPT_options	= 247,
1226 	OPT_cmd_lines	= 248,
1227 	OPT_printk	= 249,
1228 	OPT_kallsyms	= 250,
1229 	OPT_events	= 251,
1230 	OPT_systems	= 252,
1231 	OPT_ftrace	= 253,
1232 	OPT_head_event	= 254,
1233 	OPT_head_page	= 255,
1234 };
1235 
trace_dump(int argc,char ** argv)1236 void trace_dump(int argc, char **argv)
1237 {
1238 	char *input_file = NULL;
1239 	bool validate = false;
1240 	int c;
1241 
1242 	if (argc < 2)
1243 		usage(argv);
1244 
1245 	if (strcmp(argv[1], "dump") != 0)
1246 		usage(argv);
1247 	for (;;) {
1248 		int option_index = 0;
1249 		static struct option long_options[] = {
1250 			{"all", no_argument, NULL, OPT_all},
1251 			{"summary", no_argument, NULL, OPT_summary},
1252 			{"head-page", no_argument, NULL, OPT_head_page},
1253 			{"head-event", no_argument, NULL, OPT_head_event},
1254 			{"ftrace-events", no_argument, NULL, OPT_ftrace},
1255 			{"systems", no_argument, NULL, OPT_systems},
1256 			{"events", no_argument, NULL, OPT_events},
1257 			{"kallsyms", no_argument, NULL, OPT_kallsyms},
1258 			{"printk", no_argument, NULL, OPT_printk},
1259 			{"cmd-lines", no_argument, NULL, OPT_cmd_lines},
1260 			{"options", no_argument, NULL, OPT_options},
1261 			{"flyrecord", no_argument, NULL, OPT_flyrecord},
1262 			{"clock", no_argument, NULL, OPT_clock},
1263 			{"strings", no_argument, NULL, OPT_strings},
1264 			{"sections", no_argument, NULL, OPT_sections},
1265 			{"validate", no_argument, NULL, 'v'},
1266 			{"help", no_argument, NULL, '?'},
1267 			{"verbose", optional_argument, NULL, OPT_verbose},
1268 			{NULL, 0, NULL, 0}
1269 		};
1270 
1271 		c = getopt_long (argc-1, argv+1, "+hvai:",
1272 				long_options, &option_index);
1273 		if (c == -1)
1274 			break;
1275 		switch (c) {
1276 		case 'h':
1277 			usage(argv);
1278 			break;
1279 		case 'i':
1280 			input_file = optarg;
1281 			break;
1282 		case 'v':
1283 			validate = true;
1284 			break;
1285 		case OPT_all:
1286 			verbosity = 0xFFFFFFFF;
1287 			break;
1288 		case OPT_summary:
1289 			verbosity |= SUMMARY;
1290 			break;
1291 		case OPT_flyrecord:
1292 			verbosity |= FLYRECORD;
1293 			break;
1294 		case OPT_options:
1295 			verbosity |= OPTIONS;
1296 			break;
1297 		case OPT_cmd_lines:
1298 			verbosity |= CMDLINES;
1299 			break;
1300 		case OPT_printk:
1301 			verbosity |= TRACE_PRINTK;
1302 			break;
1303 		case OPT_kallsyms:
1304 			verbosity |= KALLSYMS;
1305 			break;
1306 		case OPT_events:
1307 			verbosity |= EVENT_FORMAT;
1308 			break;
1309 		case OPT_systems:
1310 			verbosity |= EVENT_SYSTEMS;
1311 			break;
1312 		case OPT_ftrace:
1313 			verbosity |= FTRACE_FORMAT;
1314 			break;
1315 		case OPT_head_event:
1316 			verbosity |= HEAD_EVENT;
1317 			break;
1318 		case OPT_head_page:
1319 			verbosity |= HEAD_PAGE;
1320 			break;
1321 		case OPT_clock:
1322 			verbosity |= CLOCK;
1323 			break;
1324 		case OPT_verbose:
1325 			if (trace_set_verbose(optarg) < 0)
1326 				die("invalid verbose level %s", optarg);
1327 			break;
1328 		case OPT_strings:
1329 			verbosity |= STRINGS;
1330 			break;
1331 		case OPT_sections:
1332 			verbosity |= SECTIONS;
1333 			break;
1334 		default:
1335 			usage(argv);
1336 		}
1337 	}
1338 
1339 	if ((argc - optind) >= 2) {
1340 		if (input_file)
1341 			usage(argv);
1342 		input_file = argv[optind + 1];
1343 	}
1344 
1345 	if (!input_file)
1346 		input_file = DEFAULT_INPUT_FILE;
1347 
1348 	if (!verbosity && !validate)
1349 		verbosity = SUMMARY;
1350 
1351 	dump_file(input_file);
1352 
1353 	if (validate)
1354 		tracecmd_plog("File %s is a valid trace-cmd file\n", input_file);
1355 }
1356