]>
Commit | Line | Data |
---|---|---|
4977bab6 | 1 | /* Dump a gcov file, for debugging use. |
a945c346 | 2 | Copyright (C) 2002-2024 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" | |
03119249 | 20 | #define INCLUDE_VECTOR |
4977bab6 ZW |
21 | #include "system.h" |
22 | #include "coretypes.h" | |
23 | #include "tm.h" | |
24 | #include "version.h" | |
2691e6d7 JM |
25 | #include "intl.h" |
26 | #include "diagnostic.h" | |
4977bab6 | 27 | #include <getopt.h> |
546d2adb | 28 | #define IN_GCOV (-1) |
4977bab6 | 29 | #include "gcov-io.h" |
e53b6e56 | 30 | #include "gcov-io.cc" |
4977bab6 | 31 | |
a6b7fff0 ML |
32 | using namespace std; |
33 | ||
be7a421e | 34 | static void dump_gcov_file (const char *); |
1d088dee AJ |
35 | static void print_prefix (const char *, unsigned, gcov_position_t); |
36 | static void print_usage (void); | |
37 | static void print_version (void); | |
ece21ff6 ML |
38 | static void tag_function (const char *, unsigned, int, unsigned); |
39 | static void tag_blocks (const char *, unsigned, int, unsigned); | |
40 | static void tag_arcs (const char *, unsigned, int, unsigned); | |
08a52331 | 41 | static void tag_conditions (const char *, unsigned, int, unsigned); |
ece21ff6 ML |
42 | static void tag_lines (const char *, unsigned, int, unsigned); |
43 | static void tag_counters (const char *, unsigned, int, unsigned); | |
44 | static void tag_summary (const char *, unsigned, int, unsigned); | |
1d088dee | 45 | extern int main (int, char **); |
4977bab6 ZW |
46 | |
47 | typedef struct tag_format | |
48 | { | |
49 | unsigned tag; | |
50 | char const *name; | |
ece21ff6 | 51 | void (*proc) (const char *, unsigned, int, unsigned); |
4977bab6 ZW |
52 | } tag_format_t; |
53 | ||
54 | static int flag_dump_contents = 0; | |
7d63a2fa | 55 | static int flag_dump_positions = 0; |
871e5ada | 56 | static int flag_dump_raw = 0; |
a6b7fff0 | 57 | static int flag_dump_stable = 0; |
4977bab6 ZW |
58 | |
59 | static const struct option options[] = | |
60 | { | |
61 | { "help", no_argument, NULL, 'h' }, | |
62 | { "version", no_argument, NULL, 'v' }, | |
63 | { "long", no_argument, NULL, 'l' }, | |
7d63a2fa | 64 | { "positions", no_argument, NULL, 'o' }, |
a6b7fff0 ML |
65 | { "raw", no_argument, NULL, 'r' }, |
66 | { "stable", no_argument, NULL, 's' }, | |
67 | {} | |
4977bab6 ZW |
68 | }; |
69 | ||
5c5059bc ML |
70 | #define VALUE_PADDING_PREFIX " " |
71 | #define VALUE_PREFIX "%2d: " | |
72 | ||
83fa8d7a | 73 | static const tag_format_t tag_table[] = |
4977bab6 ZW |
74 | { |
75 | {0, "NOP", NULL}, | |
76 | {0, "UNKNOWN", NULL}, | |
cdb23767 | 77 | {0, "COUNTERS", tag_counters}, |
4977bab6 ZW |
78 | {GCOV_TAG_FUNCTION, "FUNCTION", tag_function}, |
79 | {GCOV_TAG_BLOCKS, "BLOCKS", tag_blocks}, | |
80 | {GCOV_TAG_ARCS, "ARCS", tag_arcs}, | |
08a52331 | 81 | {GCOV_TAG_CONDS, "CONDITIONS", tag_conditions}, |
4977bab6 | 82 | {GCOV_TAG_LINES, "LINES", tag_lines}, |
4977bab6 | 83 | {GCOV_TAG_OBJECT_SUMMARY, "OBJECT_SUMMARY", tag_summary}, |
4977bab6 ZW |
84 | {0, NULL, NULL} |
85 | }; | |
86 | ||
1d088dee AJ |
87 | int |
88 | main (int argc ATTRIBUTE_UNUSED, char **argv) | |
4977bab6 ZW |
89 | { |
90 | int opt; | |
2691e6d7 JM |
91 | const char *p; |
92 | ||
93 | p = argv[0] + strlen (argv[0]); | |
94 | while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1])) | |
95 | --p; | |
96 | progname = p; | |
97 | ||
98 | xmalloc_set_program_name (progname); | |
4977bab6 | 99 | |
98a3dad4 | 100 | /* Unlock the stdio streams. */ |
2653bb0c | 101 | unlock_std_streams (); |
98a3dad4 | 102 | |
2691e6d7 JM |
103 | gcc_init_libintl (); |
104 | ||
105 | diagnostic_initialize (global_dc, 0); | |
106 | ||
a6b7fff0 | 107 | while ((opt = getopt_long (argc, argv, "hlprsvw", options, NULL)) != -1) |
4977bab6 ZW |
108 | { |
109 | switch (opt) | |
110 | { | |
111 | case 'h': | |
112 | print_usage (); | |
113 | break; | |
114 | case 'v': | |
115 | print_version (); | |
116 | break; | |
117 | case 'l': | |
118 | flag_dump_contents = 1; | |
119 | break; | |
7d63a2fa NS |
120 | case 'p': |
121 | flag_dump_positions = 1; | |
122 | break; | |
871e5ada ML |
123 | case 'r': |
124 | flag_dump_raw = 1; | |
125 | break; | |
a6b7fff0 ML |
126 | case 's': |
127 | flag_dump_stable = 1; | |
128 | break; | |
4977bab6 ZW |
129 | default: |
130 | fprintf (stderr, "unknown flag `%c'\n", opt); | |
131 | } | |
132 | } | |
1d088dee | 133 | |
4977bab6 | 134 | while (argv[optind]) |
be7a421e | 135 | dump_gcov_file (argv[optind++]); |
4977bab6 ZW |
136 | return 0; |
137 | } | |
138 | ||
139 | static void | |
1d088dee | 140 | print_usage (void) |
4977bab6 ZW |
141 | { |
142 | printf ("Usage: gcov-dump [OPTION] ... gcovfiles\n"); | |
143 | printf ("Print coverage file contents\n"); | |
144 | printf (" -h, --help Print this help\n"); | |
4977bab6 | 145 | printf (" -l, --long Dump record contents too\n"); |
7d63a2fa | 146 | printf (" -p, --positions Dump record positions\n"); |
f6ee4c4f | 147 | printf (" -r, --raw Print content records in raw format\n"); |
a6b7fff0 ML |
148 | printf (" -s, --stable Print content in stable " |
149 | "format usable for comparison\n"); | |
2f360676 | 150 | printf (" -v, --version Print version number\n"); |
39653b82 TV |
151 | printf ("\nFor bug reporting instructions, please see:\n%s.\n", |
152 | bug_report_url); | |
4977bab6 ZW |
153 | } |
154 | ||
155 | static void | |
1d088dee | 156 | print_version (void) |
4977bab6 | 157 | { |
2f41c1d6 | 158 | printf ("gcov-dump %s%s\n", pkgversion_string, version_string); |
4e053a7e | 159 | printf ("Copyright (C) 2024 Free Software Foundation, Inc.\n"); |
8ad4fc26 ML |
160 | printf ("This is free software; see the source for copying conditions. There is NO\n\ |
161 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); | |
4977bab6 ZW |
162 | } |
163 | ||
164 | static void | |
1d088dee | 165 | print_prefix (const char *filename, unsigned depth, gcov_position_t position) |
4977bab6 ZW |
166 | { |
167 | static const char prefix[] = " "; | |
1d088dee | 168 | |
7d63a2fa NS |
169 | printf ("%s:", filename); |
170 | if (flag_dump_positions) | |
5c5059bc ML |
171 | printf ("%5lu:", (unsigned long) position); |
172 | printf ("%.*s", (int) 2 * depth, prefix); | |
4977bab6 ZW |
173 | } |
174 | ||
175 | static void | |
be7a421e | 176 | dump_gcov_file (const char *filename) |
4977bab6 | 177 | { |
4977bab6 ZW |
178 | unsigned tags[4]; |
179 | unsigned depth = 0; | |
bb5307a6 | 180 | bool is_data_type; |
1d088dee | 181 | |
546d2adb | 182 | if (!gcov_open (filename, 1)) |
4977bab6 ZW |
183 | { |
184 | fprintf (stderr, "%s:cannot open\n", filename); | |
185 | return; | |
186 | } | |
1d088dee | 187 | |
4977bab6 ZW |
188 | /* magic */ |
189 | { | |
94de45d9 | 190 | unsigned magic = gcov_read_unsigned (); |
160e2e4f | 191 | unsigned version; |
160e2e4f | 192 | int endianness = 0; |
330d2e2a | 193 | char m[4], v[4]; |
b8698a0f | 194 | |
160e2e4f | 195 | if ((endianness = gcov_magic (magic, GCOV_DATA_MAGIC))) |
bb5307a6 | 196 | is_data_type = true; |
160e2e4f | 197 | else if ((endianness = gcov_magic (magic, GCOV_NOTE_MAGIC))) |
bb5307a6 | 198 | is_data_type = false; |
4977bab6 ZW |
199 | else |
200 | { | |
201 | printf ("%s:not a gcov file\n", filename); | |
546d2adb | 202 | gcov_close (); |
4977bab6 ZW |
203 | return; |
204 | } | |
160e2e4f | 205 | version = gcov_read_unsigned (); |
330d2e2a NS |
206 | GCOV_UNSIGNED2STRING (v, version); |
207 | GCOV_UNSIGNED2STRING (m, magic); | |
b8698a0f | 208 | |
bb5307a6 ML |
209 | printf ("%s:%s:magic `%.4s':version `%.4s'%s\n", filename, |
210 | is_data_type ? "data" : "note", | |
330d2e2a | 211 | m, v, endianness < 0 ? " (swapped endianness)" : ""); |
160e2e4f | 212 | if (version != GCOV_VERSION) |
4977bab6 | 213 | { |
330d2e2a | 214 | char e[4]; |
b8698a0f | 215 | |
330d2e2a NS |
216 | GCOV_UNSIGNED2STRING (e, GCOV_VERSION); |
217 | printf ("%s:warning:current version is `%.4s'\n", filename, e); | |
4977bab6 | 218 | } |
4977bab6 ZW |
219 | } |
220 | ||
dd486eb2 | 221 | /* stamp */ |
72e0c742 | 222 | unsigned stamp = gcov_read_unsigned (); |
89e93ce8 | 223 | printf ("%s:stamp %u\n", filename, stamp); |
dd486eb2 | 224 | |
72e0c742 ML |
225 | /* Checksum */ |
226 | unsigned checksum = gcov_read_unsigned (); | |
89e93ce8 | 227 | printf ("%s:checksum %u\n", filename, checksum); |
b8698a0f | 228 | |
bb5307a6 ML |
229 | if (!is_data_type) |
230 | { | |
c74bd3fb ML |
231 | printf ("%s:cwd: %s\n", filename, gcov_read_string ()); |
232 | ||
bb5307a6 ML |
233 | /* Support for unexecuted basic blocks. */ |
234 | unsigned support_unexecuted_blocks = gcov_read_unsigned (); | |
235 | if (!support_unexecuted_blocks) | |
236 | printf ("%s: has_unexecuted_block is not supported\n", filename); | |
237 | } | |
93814e2d | 238 | |
7d63a2fa | 239 | while (1) |
4977bab6 | 240 | { |
7d63a2fa | 241 | gcov_position_t base, position = gcov_position (); |
ece21ff6 | 242 | int read_length; |
7d63a2fa | 243 | unsigned tag, length; |
4977bab6 ZW |
244 | tag_format_t const *format; |
245 | unsigned tag_depth; | |
94de45d9 | 246 | int error; |
7d63a2fa NS |
247 | unsigned mask; |
248 | ||
249 | tag = gcov_read_unsigned (); | |
4977bab6 | 250 | if (!tag) |
7d63a2fa | 251 | break; |
ece21ff6 ML |
252 | read_length = (int)gcov_read_unsigned (); |
253 | length = read_length > 0 ? read_length : 0; | |
7d63a2fa NS |
254 | base = gcov_position (); |
255 | mask = GCOV_TAG_MASK (tag) >> 1; | |
256 | for (tag_depth = 4; mask; mask >>= 8) | |
4977bab6 | 257 | { |
7d63a2fa | 258 | if ((mask & 0xff) != 0xff) |
4977bab6 | 259 | { |
7d63a2fa NS |
260 | printf ("%s:tag `%08x' is invalid\n", filename, tag); |
261 | break; | |
4977bab6 | 262 | } |
7d63a2fa | 263 | tag_depth--; |
4977bab6 ZW |
264 | } |
265 | for (format = tag_table; format->name; format++) | |
266 | if (format->tag == tag) | |
267 | goto found; | |
cdb23767 | 268 | format = &tag_table[GCOV_TAG_IS_COUNTER (tag) ? 2 : 1]; |
4977bab6 ZW |
269 | found:; |
270 | if (tag) | |
271 | { | |
272 | if (depth && depth < tag_depth) | |
273 | { | |
274 | if (!GCOV_TAG_IS_SUBTAG (tags[depth - 1], tag)) | |
275 | printf ("%s:tag `%08x' is incorrectly nested\n", | |
276 | filename, tag); | |
277 | } | |
278 | depth = tag_depth; | |
279 | tags[depth - 1] = tag; | |
280 | } | |
1d088dee | 281 | |
7d63a2fa | 282 | print_prefix (filename, tag_depth, position); |
ece21ff6 | 283 | printf ("%08x:%4u:%s", tag, abs (read_length), format->name); |
4977bab6 | 284 | if (format->proc) |
ece21ff6 | 285 | (*format->proc) (filename, tag, read_length, depth); |
1d088dee | 286 | |
4977bab6 | 287 | printf ("\n"); |
94de45d9 | 288 | if (flag_dump_contents && format->proc) |
4977bab6 | 289 | { |
94de45d9 | 290 | unsigned long actual_length = gcov_position () - base; |
1d088dee | 291 | |
94de45d9 | 292 | if (actual_length > length) |
4977bab6 | 293 | printf ("%s:record size mismatch %lu bytes overread\n", |
94de45d9 NS |
294 | filename, actual_length - length); |
295 | else if (length > actual_length) | |
4977bab6 | 296 | printf ("%s:record size mismatch %lu bytes unread\n", |
94de45d9 NS |
297 | filename, length - actual_length); |
298 | } | |
474f141e | 299 | gcov_sync (base, length); |
94de45d9 NS |
300 | if ((error = gcov_is_error ())) |
301 | { | |
302 | printf (error < 0 ? "%s:counter overflow at %lu\n" : | |
9b514d25 NS |
303 | "%s:read error at %lu\n", filename, |
304 | (long unsigned) gcov_position ()); | |
94de45d9 | 305 | break; |
4977bab6 ZW |
306 | } |
307 | } | |
546d2adb | 308 | gcov_close (); |
4977bab6 ZW |
309 | } |
310 | ||
94de45d9 | 311 | static void |
1d088dee | 312 | tag_function (const char *filename ATTRIBUTE_UNUSED, |
ece21ff6 | 313 | unsigned tag ATTRIBUTE_UNUSED, int length, |
5c5059bc | 314 | unsigned depth ATTRIBUTE_UNUSED) |
4977bab6 | 315 | { |
6c9e35a5 | 316 | gcov_position_t pos = gcov_position (); |
1d088dee | 317 | |
5366b186 NS |
318 | if (!length) |
319 | printf (" placeholder"); | |
320 | else | |
94de45d9 | 321 | { |
5366b186 NS |
322 | printf (" ident=%u", gcov_read_unsigned ()); |
323 | printf (", lineno_checksum=0x%08x", gcov_read_unsigned ()); | |
bdbdc4e1 | 324 | printf (", cfg_checksum=0x%08x", gcov_read_unsigned ()); |
1d088dee | 325 | |
6c9e35a5 | 326 | if (gcov_position () - pos < (gcov_position_t) length) |
5366b186 NS |
327 | { |
328 | const char *name; | |
329 | ||
330 | name = gcov_read_string (); | |
331 | printf (", `%s'", name ? name : "NULL"); | |
136ca74e | 332 | unsigned artificial = gcov_read_unsigned (); |
5366b186 NS |
333 | name = gcov_read_string (); |
334 | printf (" %s", name ? name : "NULL"); | |
136ca74e ML |
335 | unsigned line_start = gcov_read_unsigned (); |
336 | unsigned column_start = gcov_read_unsigned (); | |
337 | unsigned line_end = gcov_read_unsigned (); | |
b8154717 ML |
338 | unsigned column_end = gcov_read_unsigned (); |
339 | printf (":%u:%u-%u:%u", line_start, column_start, | |
340 | line_end, column_end); | |
136ca74e ML |
341 | if (artificial) |
342 | printf (", artificial"); | |
5366b186 | 343 | } |
94de45d9 | 344 | } |
4977bab6 ZW |
345 | } |
346 | ||
94de45d9 | 347 | static void |
1d088dee | 348 | tag_blocks (const char *filename ATTRIBUTE_UNUSED, |
ece21ff6 | 349 | unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED, |
34769baf | 350 | unsigned depth ATTRIBUTE_UNUSED) |
4977bab6 | 351 | { |
34769baf | 352 | printf (" %u blocks", gcov_read_unsigned ()); |
4977bab6 ZW |
353 | } |
354 | ||
94de45d9 | 355 | static void |
1d088dee | 356 | tag_arcs (const char *filename ATTRIBUTE_UNUSED, |
ece21ff6 | 357 | unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED, |
5c5059bc | 358 | unsigned depth) |
4977bab6 | 359 | { |
330d2e2a | 360 | unsigned n_arcs = GCOV_TAG_ARCS_NUM (length); |
4977bab6 ZW |
361 | |
362 | printf (" %u arcs", n_arcs); | |
363 | if (flag_dump_contents) | |
364 | { | |
365 | unsigned ix; | |
94de45d9 | 366 | unsigned blockno = gcov_read_unsigned (); |
4977bab6 ZW |
367 | |
368 | for (ix = 0; ix != n_arcs; ix++) | |
369 | { | |
7d63a2fa | 370 | unsigned dst, flags; |
1d088dee | 371 | |
4977bab6 | 372 | if (!(ix & 3)) |
7d63a2fa NS |
373 | { |
374 | printf ("\n"); | |
5c5059bc ML |
375 | print_prefix (filename, depth, gcov_position ()); |
376 | printf (VALUE_PADDING_PREFIX "block %u:", blockno); | |
7d63a2fa NS |
377 | } |
378 | dst = gcov_read_unsigned (); | |
379 | flags = gcov_read_unsigned (); | |
4977bab6 | 380 | printf (" %u:%04x", dst, flags); |
8919c0d9 NS |
381 | if (flags) |
382 | { | |
383 | char c = '('; | |
384 | ||
385 | if (flags & GCOV_ARC_ON_TREE) | |
386 | printf ("%ctree", c), c = ','; | |
387 | if (flags & GCOV_ARC_FAKE) | |
388 | printf ("%cfake", c), c = ','; | |
389 | if (flags & GCOV_ARC_FALLTHROUGH) | |
390 | printf ("%cfall", c), c = ','; | |
391 | printf (")"); | |
392 | } | |
4977bab6 ZW |
393 | } |
394 | } | |
4977bab6 ZW |
395 | } |
396 | ||
08a52331 JK |
397 | /* Print number of conditions (not outcomes, i.e. if (x && y) is 2, not 4). */ |
398 | static void | |
399 | tag_conditions (const char *filename, unsigned /* tag */, int length, | |
400 | unsigned depth) | |
401 | { | |
402 | unsigned n_conditions = GCOV_TAG_CONDS_NUM (length); | |
403 | ||
404 | printf (" %u conditions", n_conditions); | |
405 | if (flag_dump_contents) | |
406 | { | |
407 | for (unsigned ix = 0; ix != n_conditions; ix++) | |
408 | { | |
409 | const unsigned blockno = gcov_read_unsigned (); | |
410 | const unsigned nterms = gcov_read_unsigned (); | |
411 | ||
412 | printf ("\n"); | |
413 | print_prefix (filename, depth, gcov_position ()); | |
414 | printf (VALUE_PADDING_PREFIX "block %u:", blockno); | |
415 | printf (" %u", nterms); | |
416 | } | |
417 | } | |
418 | } | |
94de45d9 | 419 | static void |
1d088dee | 420 | tag_lines (const char *filename ATTRIBUTE_UNUSED, |
ece21ff6 | 421 | unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED, |
5c5059bc | 422 | unsigned depth) |
4977bab6 ZW |
423 | { |
424 | if (flag_dump_contents) | |
425 | { | |
94de45d9 | 426 | unsigned blockno = gcov_read_unsigned (); |
4977bab6 ZW |
427 | char const *sep = NULL; |
428 | ||
4977bab6 ZW |
429 | while (1) |
430 | { | |
7d63a2fa | 431 | gcov_position_t position = gcov_position (); |
94de45d9 NS |
432 | const char *source = NULL; |
433 | unsigned lineno = gcov_read_unsigned (); | |
1d088dee | 434 | |
4977bab6 ZW |
435 | if (!lineno) |
436 | { | |
94de45d9 | 437 | source = gcov_read_string (); |
4977bab6 ZW |
438 | if (!source) |
439 | break; | |
440 | sep = NULL; | |
441 | } | |
1d088dee | 442 | |
4977bab6 ZW |
443 | if (!sep) |
444 | { | |
7d63a2fa | 445 | printf ("\n"); |
5c5059bc ML |
446 | print_prefix (filename, depth, position); |
447 | printf (VALUE_PADDING_PREFIX "block %u:", blockno); | |
4977bab6 ZW |
448 | sep = ""; |
449 | } | |
450 | if (lineno) | |
451 | { | |
452 | printf ("%s%u", sep, lineno); | |
453 | sep = ", "; | |
454 | } | |
455 | else | |
456 | { | |
457 | printf ("%s`%s'", sep, source); | |
458 | sep = ":"; | |
459 | } | |
460 | } | |
461 | } | |
4977bab6 ZW |
462 | } |
463 | ||
94de45d9 | 464 | static void |
1d088dee | 465 | tag_counters (const char *filename ATTRIBUTE_UNUSED, |
ece21ff6 | 466 | unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED, |
5c5059bc | 467 | unsigned depth) |
4977bab6 | 468 | { |
c77556a5 RX |
469 | #define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) NAME, |
470 | static const char *const counter_names[] = { | |
471 | #include "gcov-counter.def" | |
472 | }; | |
473 | #undef DEF_GCOV_COUNTER | |
ece21ff6 ML |
474 | int n_counts = GCOV_TAG_COUNTER_NUM (length); |
475 | bool has_zeros = n_counts < 0; | |
476 | n_counts = abs (n_counts); | |
a6b7fff0 | 477 | unsigned counter_idx = GCOV_COUNTER_FOR_TAG (tag); |
1d088dee | 478 | |
ece21ff6 | 479 | printf (" %s %u counts%s", |
a6b7fff0 | 480 | counter_names[counter_idx], n_counts, |
ece21ff6 | 481 | has_zeros ? " (all zero)" : ""); |
4977bab6 ZW |
482 | if (flag_dump_contents) |
483 | { | |
a6b7fff0 | 484 | vector<gcov_type> counters; |
ece21ff6 | 485 | for (int ix = 0; ix != n_counts; ix++) |
a6b7fff0 ML |
486 | counters.push_back (has_zeros ? 0 : gcov_read_counter ()); |
487 | ||
488 | /* Make stable sort for TOP N counters. */ | |
489 | if (flag_dump_stable) | |
490 | if (counter_idx == GCOV_COUNTER_V_INDIR | |
491 | || counter_idx == GCOV_COUNTER_V_TOPN) | |
492 | { | |
493 | unsigned start = 0; | |
494 | while (start < counters.size ()) | |
495 | { | |
496 | unsigned n = counters[start + 1]; | |
497 | ||
498 | /* Use bubble sort. */ | |
499 | for (unsigned i = 1; i <= n; ++i) | |
500 | for (unsigned j = i; j <= n; ++j) | |
501 | { | |
502 | gcov_type key1 = counters[start + 2 * i]; | |
503 | gcov_type value1 = counters[start + 2 * i + 1]; | |
504 | gcov_type key2 = counters[start + 2 * j]; | |
505 | gcov_type value2 = counters[start + 2 * j + 1]; | |
506 | ||
507 | if (value1 < value2 || (value1 == value2 && key1 < key2)) | |
508 | { | |
509 | std::swap (counters[start + 2 * i], | |
510 | counters[start + 2 * j]); | |
511 | std::swap (counters[start + 2 * i + 1], | |
512 | counters[start + 2 * j + 1]); | |
513 | } | |
514 | } | |
515 | start += 2 * (n + 1); | |
516 | } | |
517 | if (start != counters.size ()) | |
518 | abort (); | |
519 | } | |
520 | ||
521 | for (unsigned ix = 0; ix < counters.size (); ++ix) | |
4977bab6 | 522 | { |
871e5ada ML |
523 | if (flag_dump_raw) |
524 | { | |
525 | if (ix == 0) | |
526 | printf (": "); | |
527 | } | |
528 | else if (!(ix & 7)) | |
7d63a2fa NS |
529 | { |
530 | printf ("\n"); | |
5c5059bc ML |
531 | print_prefix (filename, depth, gcov_position ()); |
532 | printf (VALUE_PADDING_PREFIX VALUE_PREFIX, ix); | |
7d63a2fa | 533 | } |
1d088dee | 534 | |
a6b7fff0 | 535 | printf ("%" PRId64 " ", counters[ix]); |
4977bab6 ZW |
536 | } |
537 | } | |
4977bab6 ZW |
538 | } |
539 | ||
94de45d9 | 540 | static void |
1d088dee | 541 | tag_summary (const char *filename ATTRIBUTE_UNUSED, |
ece21ff6 | 542 | unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED, |
512cc015 | 543 | unsigned depth ATTRIBUTE_UNUSED) |
4977bab6 | 544 | { |
7f3577f5 | 545 | gcov_summary summary; |
cdb23767 | 546 | gcov_read_summary (&summary); |
512cc015 ML |
547 | printf (" runs=%d, sum_max=%" PRId64, |
548 | summary.runs, summary.sum_max); | |
4977bab6 | 549 | } |