]>
Commit | Line | Data |
---|---|---|
4977bab6 | 1 | /* Dump a gcov file, for debugging use. |
21fa2a29 | 2 | Copyright (C) 2002-2016 Free Software Foundation, Inc. |
4977bab6 ZW |
3 | Contributed by Nathan Sidwell <nathan@codesourcery.com> |
4 | ||
5 | Gcov is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
9dcd6f09 | 7 | the Free Software Foundation; either version 3, or (at your option) |
4977bab6 ZW |
8 | any later version. |
9 | ||
10 | Gcov is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
9dcd6f09 NC |
16 | along with Gcov; see the file COPYING3. If not see |
17 | <http://www.gnu.org/licenses/>. */ | |
4977bab6 ZW |
18 | |
19 | #include "config.h" | |
20 | #include "system.h" | |
21 | #include "coretypes.h" | |
22 | #include "tm.h" | |
23 | #include "version.h" | |
2691e6d7 JM |
24 | #include "intl.h" |
25 | #include "diagnostic.h" | |
4977bab6 | 26 | #include <getopt.h> |
546d2adb | 27 | #define IN_GCOV (-1) |
4977bab6 | 28 | #include "gcov-io.h" |
ca29da43 | 29 | #include "gcov-io.c" |
4977bab6 | 30 | |
be7a421e | 31 | static void dump_gcov_file (const char *); |
1d088dee AJ |
32 | static void print_prefix (const char *, unsigned, gcov_position_t); |
33 | static void print_usage (void); | |
34 | static void print_version (void); | |
35 | static void tag_function (const char *, unsigned, unsigned); | |
36 | static void tag_blocks (const char *, unsigned, unsigned); | |
37 | static void tag_arcs (const char *, unsigned, unsigned); | |
38 | static void tag_lines (const char *, unsigned, unsigned); | |
39 | static void tag_counters (const char *, unsigned, unsigned); | |
40 | static void tag_summary (const char *, unsigned, unsigned); | |
f57ddb5b TJ |
41 | static void dump_working_sets (const char *filename ATTRIBUTE_UNUSED, |
42 | const struct gcov_ctr_summary *summary); | |
1d088dee | 43 | extern int main (int, char **); |
4977bab6 ZW |
44 | |
45 | typedef struct tag_format | |
46 | { | |
47 | unsigned tag; | |
48 | char const *name; | |
94de45d9 | 49 | void (*proc) (const char *, unsigned, unsigned); |
4977bab6 ZW |
50 | } tag_format_t; |
51 | ||
52 | static int flag_dump_contents = 0; | |
7d63a2fa | 53 | static int flag_dump_positions = 0; |
f57ddb5b | 54 | static int flag_dump_working_sets = 0; |
4977bab6 ZW |
55 | |
56 | static const struct option options[] = | |
57 | { | |
58 | { "help", no_argument, NULL, 'h' }, | |
59 | { "version", no_argument, NULL, 'v' }, | |
60 | { "long", no_argument, NULL, 'l' }, | |
7d63a2fa | 61 | { "positions", no_argument, NULL, 'o' }, |
f57ddb5b | 62 | { "working-sets", no_argument, NULL, 'w' }, |
d90f9882 | 63 | { 0, 0, 0, 0 } |
4977bab6 ZW |
64 | }; |
65 | ||
83fa8d7a | 66 | static const tag_format_t tag_table[] = |
4977bab6 ZW |
67 | { |
68 | {0, "NOP", NULL}, | |
69 | {0, "UNKNOWN", NULL}, | |
cdb23767 | 70 | {0, "COUNTERS", tag_counters}, |
4977bab6 ZW |
71 | {GCOV_TAG_FUNCTION, "FUNCTION", tag_function}, |
72 | {GCOV_TAG_BLOCKS, "BLOCKS", tag_blocks}, | |
73 | {GCOV_TAG_ARCS, "ARCS", tag_arcs}, | |
74 | {GCOV_TAG_LINES, "LINES", tag_lines}, | |
4977bab6 ZW |
75 | {GCOV_TAG_OBJECT_SUMMARY, "OBJECT_SUMMARY", tag_summary}, |
76 | {GCOV_TAG_PROGRAM_SUMMARY, "PROGRAM_SUMMARY", tag_summary}, | |
4977bab6 ZW |
77 | {0, NULL, NULL} |
78 | }; | |
79 | ||
1d088dee AJ |
80 | int |
81 | main (int argc ATTRIBUTE_UNUSED, char **argv) | |
4977bab6 ZW |
82 | { |
83 | int opt; | |
2691e6d7 JM |
84 | const char *p; |
85 | ||
86 | p = argv[0] + strlen (argv[0]); | |
87 | while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1])) | |
88 | --p; | |
89 | progname = p; | |
90 | ||
91 | xmalloc_set_program_name (progname); | |
4977bab6 | 92 | |
98a3dad4 | 93 | /* Unlock the stdio streams. */ |
2653bb0c | 94 | unlock_std_streams (); |
98a3dad4 | 95 | |
2691e6d7 JM |
96 | gcc_init_libintl (); |
97 | ||
98 | diagnostic_initialize (global_dc, 0); | |
99 | ||
f57ddb5b | 100 | while ((opt = getopt_long (argc, argv, "hlpvw", options, NULL)) != -1) |
4977bab6 ZW |
101 | { |
102 | switch (opt) | |
103 | { | |
104 | case 'h': | |
105 | print_usage (); | |
106 | break; | |
107 | case 'v': | |
108 | print_version (); | |
109 | break; | |
110 | case 'l': | |
111 | flag_dump_contents = 1; | |
112 | break; | |
7d63a2fa NS |
113 | case 'p': |
114 | flag_dump_positions = 1; | |
115 | break; | |
f57ddb5b TJ |
116 | case 'w': |
117 | flag_dump_working_sets = 1; | |
118 | break; | |
4977bab6 ZW |
119 | default: |
120 | fprintf (stderr, "unknown flag `%c'\n", opt); | |
121 | } | |
122 | } | |
1d088dee | 123 | |
4977bab6 | 124 | while (argv[optind]) |
be7a421e | 125 | dump_gcov_file (argv[optind++]); |
4977bab6 ZW |
126 | return 0; |
127 | } | |
128 | ||
129 | static void | |
1d088dee | 130 | print_usage (void) |
4977bab6 ZW |
131 | { |
132 | printf ("Usage: gcov-dump [OPTION] ... gcovfiles\n"); | |
133 | printf ("Print coverage file contents\n"); | |
134 | printf (" -h, --help Print this help\n"); | |
135 | printf (" -v, --version Print version number\n"); | |
136 | printf (" -l, --long Dump record contents too\n"); | |
7d63a2fa | 137 | printf (" -p, --positions Dump record positions\n"); |
f57ddb5b | 138 | printf (" -w, --working-sets Dump working set computed from summary\n"); |
4977bab6 ZW |
139 | } |
140 | ||
141 | static void | |
1d088dee | 142 | print_version (void) |
4977bab6 | 143 | { |
2f41c1d6 | 144 | printf ("gcov-dump %s%s\n", pkgversion_string, version_string); |
21fa2a29 | 145 | printf ("Copyright (C) 2016 Free Software Foundation, Inc.\n"); |
330d2e2a NS |
146 | printf ("This is free software; see the source for copying conditions.\n" |
147 | "There is NO warranty; not even for MERCHANTABILITY or \n" | |
148 | "FITNESS FOR A PARTICULAR PURPOSE.\n\n"); | |
4977bab6 ZW |
149 | } |
150 | ||
151 | static void | |
1d088dee | 152 | print_prefix (const char *filename, unsigned depth, gcov_position_t position) |
4977bab6 ZW |
153 | { |
154 | static const char prefix[] = " "; | |
1d088dee | 155 | |
7d63a2fa NS |
156 | printf ("%s:", filename); |
157 | if (flag_dump_positions) | |
158 | printf ("%lu:", (unsigned long) position); | |
159 | printf ("%.*s", (int) depth, prefix); | |
4977bab6 ZW |
160 | } |
161 | ||
162 | static void | |
be7a421e | 163 | dump_gcov_file (const char *filename) |
4977bab6 | 164 | { |
4977bab6 ZW |
165 | unsigned tags[4]; |
166 | unsigned depth = 0; | |
1d088dee | 167 | |
546d2adb | 168 | if (!gcov_open (filename, 1)) |
4977bab6 ZW |
169 | { |
170 | fprintf (stderr, "%s:cannot open\n", filename); | |
171 | return; | |
172 | } | |
1d088dee | 173 | |
4977bab6 ZW |
174 | /* magic */ |
175 | { | |
94de45d9 | 176 | unsigned magic = gcov_read_unsigned (); |
160e2e4f | 177 | unsigned version; |
4977bab6 | 178 | const char *type = NULL; |
160e2e4f | 179 | int endianness = 0; |
330d2e2a | 180 | char m[4], v[4]; |
b8698a0f | 181 | |
160e2e4f | 182 | if ((endianness = gcov_magic (magic, GCOV_DATA_MAGIC))) |
4977bab6 | 183 | type = "data"; |
160e2e4f NS |
184 | else if ((endianness = gcov_magic (magic, GCOV_NOTE_MAGIC))) |
185 | type = "note"; | |
4977bab6 ZW |
186 | else |
187 | { | |
188 | printf ("%s:not a gcov file\n", filename); | |
546d2adb | 189 | gcov_close (); |
4977bab6 ZW |
190 | return; |
191 | } | |
160e2e4f | 192 | version = gcov_read_unsigned (); |
330d2e2a NS |
193 | GCOV_UNSIGNED2STRING (v, version); |
194 | GCOV_UNSIGNED2STRING (m, magic); | |
b8698a0f | 195 | |
160e2e4f | 196 | printf ("%s:%s:magic `%.4s':version `%.4s'%s\n", filename, type, |
330d2e2a | 197 | m, v, endianness < 0 ? " (swapped endianness)" : ""); |
160e2e4f | 198 | if (version != GCOV_VERSION) |
4977bab6 | 199 | { |
330d2e2a | 200 | char e[4]; |
b8698a0f | 201 | |
330d2e2a NS |
202 | GCOV_UNSIGNED2STRING (e, GCOV_VERSION); |
203 | printf ("%s:warning:current version is `%.4s'\n", filename, e); | |
4977bab6 | 204 | } |
4977bab6 ZW |
205 | } |
206 | ||
dd486eb2 NS |
207 | /* stamp */ |
208 | { | |
209 | unsigned stamp = gcov_read_unsigned (); | |
210 | ||
211 | printf ("%s:stamp %lu\n", filename, (unsigned long)stamp); | |
212 | } | |
b8698a0f | 213 | |
7d63a2fa | 214 | while (1) |
4977bab6 | 215 | { |
7d63a2fa NS |
216 | gcov_position_t base, position = gcov_position (); |
217 | unsigned tag, length; | |
4977bab6 ZW |
218 | tag_format_t const *format; |
219 | unsigned tag_depth; | |
94de45d9 | 220 | int error; |
7d63a2fa NS |
221 | unsigned mask; |
222 | ||
223 | tag = gcov_read_unsigned (); | |
4977bab6 | 224 | if (!tag) |
7d63a2fa NS |
225 | break; |
226 | length = gcov_read_unsigned (); | |
227 | base = gcov_position (); | |
228 | mask = GCOV_TAG_MASK (tag) >> 1; | |
229 | for (tag_depth = 4; mask; mask >>= 8) | |
4977bab6 | 230 | { |
7d63a2fa | 231 | if ((mask & 0xff) != 0xff) |
4977bab6 | 232 | { |
7d63a2fa NS |
233 | printf ("%s:tag `%08x' is invalid\n", filename, tag); |
234 | break; | |
4977bab6 | 235 | } |
7d63a2fa | 236 | tag_depth--; |
4977bab6 ZW |
237 | } |
238 | for (format = tag_table; format->name; format++) | |
239 | if (format->tag == tag) | |
240 | goto found; | |
cdb23767 | 241 | format = &tag_table[GCOV_TAG_IS_COUNTER (tag) ? 2 : 1]; |
4977bab6 ZW |
242 | found:; |
243 | if (tag) | |
244 | { | |
245 | if (depth && depth < tag_depth) | |
246 | { | |
247 | if (!GCOV_TAG_IS_SUBTAG (tags[depth - 1], tag)) | |
248 | printf ("%s:tag `%08x' is incorrectly nested\n", | |
249 | filename, tag); | |
250 | } | |
251 | depth = tag_depth; | |
252 | tags[depth - 1] = tag; | |
253 | } | |
1d088dee | 254 | |
7d63a2fa | 255 | print_prefix (filename, tag_depth, position); |
4977bab6 ZW |
256 | printf ("%08x:%4u:%s", tag, length, format->name); |
257 | if (format->proc) | |
94de45d9 | 258 | (*format->proc) (filename, tag, length); |
1d088dee | 259 | |
4977bab6 | 260 | printf ("\n"); |
94de45d9 | 261 | if (flag_dump_contents && format->proc) |
4977bab6 | 262 | { |
94de45d9 | 263 | unsigned long actual_length = gcov_position () - base; |
1d088dee | 264 | |
94de45d9 | 265 | if (actual_length > length) |
4977bab6 | 266 | printf ("%s:record size mismatch %lu bytes overread\n", |
94de45d9 NS |
267 | filename, actual_length - length); |
268 | else if (length > actual_length) | |
4977bab6 | 269 | printf ("%s:record size mismatch %lu bytes unread\n", |
94de45d9 NS |
270 | filename, length - actual_length); |
271 | } | |
474f141e | 272 | gcov_sync (base, length); |
94de45d9 NS |
273 | if ((error = gcov_is_error ())) |
274 | { | |
275 | printf (error < 0 ? "%s:counter overflow at %lu\n" : | |
9b514d25 NS |
276 | "%s:read error at %lu\n", filename, |
277 | (long unsigned) gcov_position ()); | |
94de45d9 | 278 | break; |
4977bab6 ZW |
279 | } |
280 | } | |
546d2adb | 281 | gcov_close (); |
4977bab6 ZW |
282 | } |
283 | ||
94de45d9 | 284 | static void |
1d088dee | 285 | tag_function (const char *filename ATTRIBUTE_UNUSED, |
5366b186 | 286 | unsigned tag ATTRIBUTE_UNUSED, unsigned length) |
4977bab6 | 287 | { |
94de45d9 | 288 | unsigned long pos = gcov_position (); |
1d088dee | 289 | |
5366b186 NS |
290 | if (!length) |
291 | printf (" placeholder"); | |
292 | else | |
94de45d9 | 293 | { |
5366b186 NS |
294 | printf (" ident=%u", gcov_read_unsigned ()); |
295 | printf (", lineno_checksum=0x%08x", gcov_read_unsigned ()); | |
bdbdc4e1 | 296 | printf (", cfg_checksum=0x%08x", gcov_read_unsigned ()); |
1d088dee | 297 | |
5366b186 NS |
298 | if (gcov_position () - pos < length) |
299 | { | |
300 | const char *name; | |
301 | ||
302 | name = gcov_read_string (); | |
303 | printf (", `%s'", name ? name : "NULL"); | |
304 | name = gcov_read_string (); | |
305 | printf (" %s", name ? name : "NULL"); | |
306 | printf (":%u", gcov_read_unsigned ()); | |
307 | } | |
94de45d9 | 308 | } |
4977bab6 ZW |
309 | } |
310 | ||
94de45d9 | 311 | static void |
1d088dee AJ |
312 | tag_blocks (const char *filename ATTRIBUTE_UNUSED, |
313 | unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) | |
4977bab6 | 314 | { |
330d2e2a | 315 | unsigned n_blocks = GCOV_TAG_BLOCKS_NUM (length); |
1d088dee | 316 | |
4977bab6 ZW |
317 | printf (" %u blocks", n_blocks); |
318 | ||
319 | if (flag_dump_contents) | |
320 | { | |
321 | unsigned ix; | |
322 | ||
323 | for (ix = 0; ix != n_blocks; ix++) | |
324 | { | |
4977bab6 | 325 | if (!(ix & 7)) |
7d63a2fa NS |
326 | { |
327 | printf ("\n"); | |
328 | print_prefix (filename, 0, gcov_position ()); | |
329 | printf ("\t\t%u", ix); | |
330 | } | |
94de45d9 | 331 | printf (" %04x", gcov_read_unsigned ()); |
4977bab6 | 332 | } |
4977bab6 | 333 | } |
4977bab6 ZW |
334 | } |
335 | ||
94de45d9 | 336 | static void |
1d088dee AJ |
337 | tag_arcs (const char *filename ATTRIBUTE_UNUSED, |
338 | unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) | |
4977bab6 | 339 | { |
330d2e2a | 340 | unsigned n_arcs = GCOV_TAG_ARCS_NUM (length); |
4977bab6 ZW |
341 | |
342 | printf (" %u arcs", n_arcs); | |
343 | if (flag_dump_contents) | |
344 | { | |
345 | unsigned ix; | |
94de45d9 | 346 | unsigned blockno = gcov_read_unsigned (); |
4977bab6 ZW |
347 | |
348 | for (ix = 0; ix != n_arcs; ix++) | |
349 | { | |
7d63a2fa | 350 | unsigned dst, flags; |
1d088dee | 351 | |
4977bab6 | 352 | if (!(ix & 3)) |
7d63a2fa NS |
353 | { |
354 | printf ("\n"); | |
355 | print_prefix (filename, 0, gcov_position ()); | |
356 | printf ("\tblock %u:", blockno); | |
357 | } | |
358 | dst = gcov_read_unsigned (); | |
359 | flags = gcov_read_unsigned (); | |
4977bab6 | 360 | printf (" %u:%04x", dst, flags); |
8919c0d9 NS |
361 | if (flags) |
362 | { | |
363 | char c = '('; | |
364 | ||
365 | if (flags & GCOV_ARC_ON_TREE) | |
366 | printf ("%ctree", c), c = ','; | |
367 | if (flags & GCOV_ARC_FAKE) | |
368 | printf ("%cfake", c), c = ','; | |
369 | if (flags & GCOV_ARC_FALLTHROUGH) | |
370 | printf ("%cfall", c), c = ','; | |
371 | printf (")"); | |
372 | } | |
4977bab6 ZW |
373 | } |
374 | } | |
4977bab6 ZW |
375 | } |
376 | ||
94de45d9 | 377 | static void |
1d088dee AJ |
378 | tag_lines (const char *filename ATTRIBUTE_UNUSED, |
379 | unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) | |
4977bab6 ZW |
380 | { |
381 | if (flag_dump_contents) | |
382 | { | |
94de45d9 | 383 | unsigned blockno = gcov_read_unsigned (); |
4977bab6 ZW |
384 | char const *sep = NULL; |
385 | ||
4977bab6 ZW |
386 | while (1) |
387 | { | |
7d63a2fa | 388 | gcov_position_t position = gcov_position (); |
94de45d9 NS |
389 | const char *source = NULL; |
390 | unsigned lineno = gcov_read_unsigned (); | |
1d088dee | 391 | |
4977bab6 ZW |
392 | if (!lineno) |
393 | { | |
94de45d9 | 394 | source = gcov_read_string (); |
4977bab6 ZW |
395 | if (!source) |
396 | break; | |
397 | sep = NULL; | |
398 | } | |
1d088dee | 399 | |
4977bab6 ZW |
400 | if (!sep) |
401 | { | |
7d63a2fa NS |
402 | printf ("\n"); |
403 | print_prefix (filename, 0, position); | |
404 | printf ("\tblock %u:", blockno); | |
4977bab6 ZW |
405 | sep = ""; |
406 | } | |
407 | if (lineno) | |
408 | { | |
409 | printf ("%s%u", sep, lineno); | |
410 | sep = ", "; | |
411 | } | |
412 | else | |
413 | { | |
414 | printf ("%s`%s'", sep, source); | |
415 | sep = ":"; | |
416 | } | |
417 | } | |
418 | } | |
4977bab6 ZW |
419 | } |
420 | ||
94de45d9 | 421 | static void |
1d088dee AJ |
422 | tag_counters (const char *filename ATTRIBUTE_UNUSED, |
423 | unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) | |
4977bab6 | 424 | { |
c77556a5 RX |
425 | #define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) NAME, |
426 | static const char *const counter_names[] = { | |
427 | #include "gcov-counter.def" | |
428 | }; | |
429 | #undef DEF_GCOV_COUNTER | |
330d2e2a | 430 | unsigned n_counts = GCOV_TAG_COUNTER_NUM (length); |
1d088dee | 431 | |
cdb23767 NS |
432 | printf (" %s %u counts", |
433 | counter_names[GCOV_COUNTER_FOR_TAG (tag)], n_counts); | |
4977bab6 ZW |
434 | if (flag_dump_contents) |
435 | { | |
436 | unsigned ix; | |
437 | ||
438 | for (ix = 0; ix != n_counts; ix++) | |
439 | { | |
7d63a2fa | 440 | gcov_type count; |
1d088dee | 441 | |
4977bab6 | 442 | if (!(ix & 7)) |
7d63a2fa NS |
443 | { |
444 | printf ("\n"); | |
445 | print_prefix (filename, 0, gcov_position ()); | |
446 | printf ("\t\t%u", ix); | |
447 | } | |
1d088dee | 448 | |
7d63a2fa | 449 | count = gcov_read_counter (); |
4977bab6 | 450 | printf (" "); |
16998094 | 451 | printf ("%" PRId64, count); |
4977bab6 ZW |
452 | } |
453 | } | |
4977bab6 ZW |
454 | } |
455 | ||
94de45d9 | 456 | static void |
1d088dee AJ |
457 | tag_summary (const char *filename ATTRIBUTE_UNUSED, |
458 | unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) | |
4977bab6 ZW |
459 | { |
460 | struct gcov_summary summary; | |
9f71de84 TJ |
461 | unsigned ix, h_ix; |
462 | gcov_bucket_type *histo_bucket; | |
1d088dee | 463 | |
cdb23767 | 464 | gcov_read_summary (&summary); |
7c393241 | 465 | printf (" checksum=0x%08x", summary.checksum); |
1d088dee | 466 | |
63d628b2 | 467 | for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++) |
cdb23767 | 468 | { |
7d63a2fa NS |
469 | printf ("\n"); |
470 | print_prefix (filename, 0, 0); | |
471 | printf ("\t\tcounts=%u, runs=%u", | |
cdb23767 | 472 | summary.ctrs[ix].num, summary.ctrs[ix].runs); |
1d088dee | 473 | |
16998094 | 474 | printf (", sum_all=%" PRId64, |
a9243bfc | 475 | (int64_t)summary.ctrs[ix].sum_all); |
16998094 | 476 | printf (", run_max=%" PRId64, |
a9243bfc | 477 | (int64_t)summary.ctrs[ix].run_max); |
16998094 | 478 | printf (", sum_max=%" PRId64, |
a9243bfc | 479 | (int64_t)summary.ctrs[ix].sum_max); |
9f71de84 TJ |
480 | if (ix != GCOV_COUNTER_ARCS) |
481 | continue; | |
482 | printf ("\n"); | |
483 | print_prefix (filename, 0, 0); | |
484 | printf ("\t\tcounter histogram:"); | |
485 | for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) | |
486 | { | |
487 | histo_bucket = &summary.ctrs[ix].histogram[h_ix]; | |
488 | if (!histo_bucket->num_counters) | |
489 | continue; | |
490 | printf ("\n"); | |
491 | print_prefix (filename, 0, 0); | |
492 | printf ("\t\t%d: num counts=%u, min counter=" | |
16998094 JM |
493 | "%" PRId64 ", cum_counter=" |
494 | "%" PRId64, | |
9f71de84 | 495 | h_ix, histo_bucket->num_counters, |
a9243bfc RB |
496 | (int64_t)histo_bucket->min_value, |
497 | (int64_t)histo_bucket->cum_value); | |
9f71de84 | 498 | } |
f57ddb5b TJ |
499 | if (flag_dump_working_sets) |
500 | dump_working_sets (filename, &summary.ctrs[ix]); | |
501 | } | |
502 | } | |
503 | ||
504 | static void | |
505 | dump_working_sets (const char *filename ATTRIBUTE_UNUSED, | |
506 | const struct gcov_ctr_summary *summary) | |
507 | { | |
508 | gcov_working_set_t gcov_working_sets[NUM_GCOV_WORKING_SETS]; | |
509 | unsigned ws_ix, pctinc, pct; | |
510 | gcov_working_set_t *ws_info; | |
511 | ||
512 | compute_working_sets (summary, gcov_working_sets); | |
513 | ||
514 | printf ("\n"); | |
515 | print_prefix (filename, 0, 0); | |
516 | printf ("\t\tcounter working sets:"); | |
517 | /* Multiply the percentage by 100 to avoid float. */ | |
518 | pctinc = 100 * 100 / NUM_GCOV_WORKING_SETS; | |
519 | for (ws_ix = 0, pct = pctinc; ws_ix < NUM_GCOV_WORKING_SETS; | |
520 | ws_ix++, pct += pctinc) | |
521 | { | |
522 | if (ws_ix == NUM_GCOV_WORKING_SETS - 1) | |
523 | pct = 9990; | |
524 | ws_info = &gcov_working_sets[ws_ix]; | |
525 | /* Print out the percentage using int arithmatic to avoid float. */ | |
526 | printf ("\n"); | |
527 | print_prefix (filename, 0, 0); | |
528 | printf ("\t\t%u.%02u%%: num counts=%u, min counter=" | |
16998094 | 529 | "%" PRId64, |
f57ddb5b TJ |
530 | pct / 100, pct - (pct / 100 * 100), |
531 | ws_info->num_counters, | |
a9243bfc | 532 | (int64_t)ws_info->min_counter); |
cdb23767 | 533 | } |
4977bab6 | 534 | } |