@@ -422,6 +422,30 @@ static void dump_option_string(int fd, int size, char *desc)
read_dump_string(fd, size, OPTIONS);
}
+static void dump_section_header(int fd, enum dump_items v, unsigned short *flags)
+{
+ unsigned long long offset;
+ unsigned short fl;
+ char buf[DUMP_SIZE];
+ unsigned short id;
+ int size;
+
+ offset = lseek64(fd, 0, SEEK_CUR);
+ if (read_file_number(fd, &id, 2))
+ die("cannot read the section id");
+ if (read_file_string(fd, buf, DUMP_SIZE))
+ die("no section description");
+ if (read_file_number(fd, &fl, 2))
+ die("cannot read the section flags");
+ if (read_file_number(fd, &size, 4))
+ die("cannot read section size");
+ do_print(v, "\t[Section %d @ %lld: \"%s\", flags 0x%X, %d bytes]\n",
+ id, offset, buf, fl, size);
+
+ if (flags)
+ *flags = fl;
+}
+
static void dump_option_buffer(int fd, int size)
{
unsigned long long offset;
@@ -591,25 +615,47 @@ void dump_option_tsc2nsec(int fd, int size)
do_print(OPTIONS, "%d %d %llu [multiplier, shift, offset]\n", mult, shift, offset);
}
-static void dump_options(int fd)
+static int dump_options_read(int fd);
+
+static int dump_option_done(int fd, int size)
+{
+ unsigned long long offset;
+
+ do_print(OPTIONS, "\t\t[Option DONE, %d bytes]\n", size);
+
+ if (file_version < 7 || size < 8)
+ return 0;
+ if (read_file_number(fd, &offset, 8))
+ die("cannot read the next options offset");
+ do_print(OPTIONS, "%lld\n", offset);
+ if (!offset)
+ return 0;
+
+ if (lseek64(fd, offset, SEEK_SET) == (off_t)-1)
+ die("cannot goto next options offset %lld", offset);
+ return dump_options_read(fd);
+}
+
+static int dump_options_read(int fd)
{
+ unsigned short flags = 0;
unsigned short option;
unsigned int size;
int count = 0;
+ if (file_version >= 7)
+ dump_section_header(fd, OPTIONS, &flags);
+ if ((flags & TRACECMD_SEC_FL_COMPRESS) && uncompress_block())
+ die("cannot uncompress file block");
+
for (;;) {
if (read_file_number(fd, &option, 2))
die("cannot read the option id");
- if (!option)
+ if (option == TRACECMD_OPTION_DONE && file_version < 7)
break;
if (read_file_number(fd, &size, 4))
die("cannot read the option size");
-
count++;
- if (!DUMP_CHECK(OPTIONS) && !DUMP_CHECK(CLOCK) && !DUMP_CHECK(SUMMARY)) {
- lseek64(fd, size, SEEK_CUR);
- continue;
- }
switch (option) {
case TRACECMD_OPTION_DATE:
dump_option_string(fd, size, "DATE");
@@ -621,7 +667,8 @@ static void dump_options(int fd)
dump_option_buffer(fd, size);
break;
case TRACECMD_OPTION_TRACECLOCK:
- dump_option_string(fd, size, "TRACECLOCK");
+ do_print(OPTIONS, "\t\t[Option TRACECLOCK, %d bytes]\n", size);
+ read_dump_string(fd, size, OPTIONS | CLOCK);
has_clock = 1;
break;
case TRACECMD_OPTION_UNAME:
@@ -654,6 +701,10 @@ static void dump_options(int fd)
case TRACECMD_OPTION_TSC2NSEC:
dump_option_tsc2nsec(fd, size);
break;
+ case TRACECMD_OPTION_DONE:
+ uncompress_reset();
+ count += dump_option_done(fd, size);
+ return count;
default:
do_print(OPTIONS, " %d %d\t[Unknown option, size - skipping]\n",
option, size);
@@ -661,8 +712,16 @@ static void dump_options(int fd)
break;
}
}
- do_print(SUMMARY, "\t[%d options]\n", count);
+ uncompress_reset();
+ return count;
+}
+
+static void dump_options(int fd)
+{
+ int count;
+ count = dump_options_read(fd);
+ do_print(SUMMARY|OPTIONS, "\t[%d options]\n", count);
}
static void dump_latency(int fd)
Trace file version 7 supports multiple options sections in the file. The DONE option is extended to hold the offset to the next options section. A new logic for handling the extended DONE option and to read recursively all options sections is added. Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com> --- tracecmd/trace-dump.c | 77 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 9 deletions(-)