File: | build/gcc/gcov-dump.c |
Warning: | line 376, column 25 Although the value stored to 'c' is used in the enclosing expression, the value is never actually read from 'c' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Dump a gcov file, for debugging use. |
2 | Copyright (C) 2002-2021 Free Software Foundation, Inc. |
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 |
7 | the Free Software Foundation; either version 3, or (at your option) |
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 |
16 | along with Gcov; see the file COPYING3. If not see |
17 | <http://www.gnu.org/licenses/>. */ |
18 | |
19 | #include "config.h" |
20 | #include "system.h" |
21 | #include "coretypes.h" |
22 | #include "tm.h" |
23 | #include "version.h" |
24 | #include "intl.h" |
25 | #include "diagnostic.h" |
26 | #include <getopt.h> |
27 | #define IN_GCOV(-1) (-1) |
28 | #include "gcov-io.h" |
29 | #include "gcov-io.c" |
30 | |
31 | static void dump_gcov_file (const char *); |
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, int, unsigned); |
36 | static void tag_blocks (const char *, unsigned, int, unsigned); |
37 | static void tag_arcs (const char *, unsigned, int, unsigned); |
38 | static void tag_lines (const char *, unsigned, int, unsigned); |
39 | static void tag_counters (const char *, unsigned, int, unsigned); |
40 | static void tag_summary (const char *, unsigned, int, unsigned); |
41 | extern int main (int, char **); |
42 | |
43 | typedef struct tag_format |
44 | { |
45 | unsigned tag; |
46 | char const *name; |
47 | void (*proc) (const char *, unsigned, int, unsigned); |
48 | } tag_format_t; |
49 | |
50 | static int flag_dump_contents = 0; |
51 | static int flag_dump_positions = 0; |
52 | static int flag_dump_raw = 0; |
53 | |
54 | static const struct option options[] = |
55 | { |
56 | { "help", no_argument0, NULL__null, 'h' }, |
57 | { "version", no_argument0, NULL__null, 'v' }, |
58 | { "long", no_argument0, NULL__null, 'l' }, |
59 | { "positions", no_argument0, NULL__null, 'o' }, |
60 | { 0, 0, 0, 0 } |
61 | }; |
62 | |
63 | #define VALUE_PADDING_PREFIX" " " " |
64 | #define VALUE_PREFIX"%2d: " "%2d: " |
65 | |
66 | static const tag_format_t tag_table[] = |
67 | { |
68 | {0, "NOP", NULL__null}, |
69 | {0, "UNKNOWN", NULL__null}, |
70 | {0, "COUNTERS", tag_counters}, |
71 | {GCOV_TAG_FUNCTION((gcov_unsigned_t)0x01000000), "FUNCTION", tag_function}, |
72 | {GCOV_TAG_BLOCKS((gcov_unsigned_t)0x01410000), "BLOCKS", tag_blocks}, |
73 | {GCOV_TAG_ARCS((gcov_unsigned_t)0x01430000), "ARCS", tag_arcs}, |
74 | {GCOV_TAG_LINES((gcov_unsigned_t)0x01450000), "LINES", tag_lines}, |
75 | {GCOV_TAG_OBJECT_SUMMARY((gcov_unsigned_t)0xa1000000), "OBJECT_SUMMARY", tag_summary}, |
76 | {0, NULL__null, NULL__null} |
77 | }; |
78 | |
79 | int |
80 | main (int argc ATTRIBUTE_UNUSED__attribute__ ((__unused__)), char **argv) |
81 | { |
82 | int opt; |
83 | const char *p; |
84 | |
85 | p = argv[0] + strlen (argv[0]); |
86 | while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1])(((p[-1]) == '/') || (((p[-1]) == '\\') && (0)))) |
87 | --p; |
88 | progname = p; |
89 | |
90 | xmalloc_set_program_name (progname); |
91 | |
92 | /* Unlock the stdio streams. */ |
93 | unlock_std_streams (); |
94 | |
95 | gcc_init_libintl (); |
96 | |
97 | diagnostic_initialize (global_dc, 0); |
98 | |
99 | while ((opt = getopt_long (argc, argv, "hlprvw", options, NULL__null)) != -1) |
100 | { |
101 | switch (opt) |
102 | { |
103 | case 'h': |
104 | print_usage (); |
105 | break; |
106 | case 'v': |
107 | print_version (); |
108 | break; |
109 | case 'l': |
110 | flag_dump_contents = 1; |
111 | break; |
112 | case 'p': |
113 | flag_dump_positions = 1; |
114 | break; |
115 | case 'r': |
116 | flag_dump_raw = 1; |
117 | break; |
118 | default: |
119 | fprintf (stderrstderr, "unknown flag `%c'\n", opt); |
120 | } |
121 | } |
122 | |
123 | while (argv[optind]) |
124 | dump_gcov_file (argv[optind++]); |
125 | return 0; |
126 | } |
127 | |
128 | static void |
129 | print_usage (void) |
130 | { |
131 | printf ("Usage: gcov-dump [OPTION] ... gcovfiles\n"); |
132 | printf ("Print coverage file contents\n"); |
133 | printf (" -h, --help Print this help\n"); |
134 | printf (" -l, --long Dump record contents too\n"); |
135 | printf (" -p, --positions Dump record positions\n"); |
136 | printf (" -r, --raw Print content records in raw format\n"); |
137 | printf (" -v, --version Print version number\n"); |
138 | printf ("\nFor bug reporting instructions, please see:\n%s.\n", |
139 | bug_report_url); |
140 | } |
141 | |
142 | static void |
143 | print_version (void) |
144 | { |
145 | printf ("gcov-dump %s%s\n", pkgversion_string, version_string); |
146 | printf ("Copyright (C) 2021 Free Software Foundation, Inc.\n"); |
147 | printf ("This is free software; see the source for copying conditions. There is NO\n\ |
148 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); |
149 | } |
150 | |
151 | static void |
152 | print_prefix (const char *filename, unsigned depth, gcov_position_t position) |
153 | { |
154 | static const char prefix[] = " "; |
155 | |
156 | printf ("%s:", filename); |
157 | if (flag_dump_positions) |
158 | printf ("%5lu:", (unsigned long) position); |
159 | printf ("%.*s", (int) 2 * depth, prefix); |
160 | } |
161 | |
162 | static void |
163 | dump_gcov_file (const char *filename) |
164 | { |
165 | unsigned tags[4]; |
166 | unsigned depth = 0; |
167 | bool is_data_type; |
168 | |
169 | if (!gcov_open (filename, 1)) |
170 | { |
171 | fprintf (stderrstderr, "%s:cannot open\n", filename); |
172 | return; |
173 | } |
174 | |
175 | /* magic */ |
176 | { |
177 | unsigned magic = gcov_read_unsigned (); |
178 | unsigned version; |
179 | int endianness = 0; |
180 | char m[4], v[4]; |
181 | |
182 | if ((endianness = gcov_magic (magic, GCOV_DATA_MAGIC((gcov_unsigned_t)0x67636461)))) |
183 | is_data_type = true; |
184 | else if ((endianness = gcov_magic (magic, GCOV_NOTE_MAGIC((gcov_unsigned_t)0x67636e6f)))) |
185 | is_data_type = false; |
186 | else |
187 | { |
188 | printf ("%s:not a gcov file\n", filename); |
189 | gcov_close (); |
190 | return; |
191 | } |
192 | version = gcov_read_unsigned (); |
193 | GCOV_UNSIGNED2STRING (v, version)((v)[0] = (char)((version) >> 24), (v)[1] = (char)((version ) >> 16), (v)[2] = (char)((version) >> 8), (v)[3] = (char)((version) >> 0)); |
194 | GCOV_UNSIGNED2STRING (m, magic)((m)[0] = (char)((magic) >> 24), (m)[1] = (char)((magic ) >> 16), (m)[2] = (char)((magic) >> 8), (m)[3] = (char)((magic) >> 0)); |
195 | |
196 | printf ("%s:%s:magic `%.4s':version `%.4s'%s\n", filename, |
197 | is_data_type ? "data" : "note", |
198 | m, v, endianness < 0 ? " (swapped endianness)" : ""); |
199 | if (version != GCOV_VERSION((gcov_unsigned_t)0x42313065)) |
200 | { |
201 | char e[4]; |
202 | |
203 | GCOV_UNSIGNED2STRING (e, GCOV_VERSION)((e)[0] = (char)((((gcov_unsigned_t)0x42313065)) >> 24) , (e)[1] = (char)((((gcov_unsigned_t)0x42313065)) >> 16 ), (e)[2] = (char)((((gcov_unsigned_t)0x42313065)) >> 8 ), (e)[3] = (char)((((gcov_unsigned_t)0x42313065)) >> 0 )); |
204 | printf ("%s:warning:current version is `%.4s'\n", filename, e); |
205 | } |
206 | } |
207 | |
208 | /* stamp */ |
209 | { |
210 | unsigned stamp = gcov_read_unsigned (); |
211 | |
212 | printf ("%s:stamp %lu\n", filename, (unsigned long)stamp); |
213 | } |
214 | |
215 | if (!is_data_type) |
216 | { |
217 | printf ("%s:cwd: %s\n", filename, gcov_read_string ()); |
218 | |
219 | /* Support for unexecuted basic blocks. */ |
220 | unsigned support_unexecuted_blocks = gcov_read_unsigned (); |
221 | if (!support_unexecuted_blocks) |
222 | printf ("%s: has_unexecuted_block is not supported\n", filename); |
223 | } |
224 | |
225 | while (1) |
226 | { |
227 | gcov_position_t base, position = gcov_position (); |
228 | int read_length; |
229 | unsigned tag, length; |
230 | tag_format_t const *format; |
231 | unsigned tag_depth; |
232 | int error; |
233 | unsigned mask; |
234 | |
235 | tag = gcov_read_unsigned (); |
236 | if (!tag) |
237 | break; |
238 | read_length = (int)gcov_read_unsigned (); |
239 | length = read_length > 0 ? read_length : 0; |
240 | base = gcov_position (); |
241 | mask = GCOV_TAG_MASK (tag)(((tag) - 1) ^ (tag)) >> 1; |
242 | for (tag_depth = 4; mask; mask >>= 8) |
243 | { |
244 | if ((mask & 0xff) != 0xff) |
245 | { |
246 | printf ("%s:tag `%08x' is invalid\n", filename, tag); |
247 | break; |
248 | } |
249 | tag_depth--; |
250 | } |
251 | for (format = tag_table; format->name; format++) |
252 | if (format->tag == tag) |
253 | goto found; |
254 | format = &tag_table[GCOV_TAG_IS_COUNTER (tag)(!((tag) & 0xFFFF) && ((unsigned)(((tag) - ((gcov_unsigned_t )0x01a10000)) >> 17)) < GCOV_COUNTERS) ? 2 : 1]; |
255 | found:; |
256 | if (tag) |
257 | { |
258 | if (depth && depth < tag_depth) |
259 | { |
260 | if (!GCOV_TAG_IS_SUBTAG (tags[depth - 1], tag)((((tags[depth - 1]) - 1) ^ (tags[depth - 1])) >> 8 == ( ((tag) - 1) ^ (tag)) && !(((tag) ^ (tags[depth - 1])) & ~(((tags[depth - 1]) - 1) ^ (tags[depth - 1]))))) |
261 | printf ("%s:tag `%08x' is incorrectly nested\n", |
262 | filename, tag); |
263 | } |
264 | depth = tag_depth; |
265 | tags[depth - 1] = tag; |
266 | } |
267 | |
268 | print_prefix (filename, tag_depth, position); |
269 | printf ("%08x:%4u:%s", tag, abs (read_length), format->name); |
270 | if (format->proc) |
271 | (*format->proc) (filename, tag, read_length, depth); |
272 | |
273 | printf ("\n"); |
274 | if (flag_dump_contents && format->proc) |
275 | { |
276 | unsigned long actual_length = gcov_position () - base; |
277 | |
278 | if (actual_length > length) |
279 | printf ("%s:record size mismatch %lu bytes overread\n", |
280 | filename, actual_length - length); |
281 | else if (length > actual_length) |
282 | printf ("%s:record size mismatch %lu bytes unread\n", |
283 | filename, length - actual_length); |
284 | } |
285 | gcov_sync (base, length); |
286 | if ((error = gcov_is_error ())) |
287 | { |
288 | printf (error < 0 ? "%s:counter overflow at %lu\n" : |
289 | "%s:read error at %lu\n", filename, |
290 | (long unsigned) gcov_position ()); |
291 | break; |
292 | } |
293 | } |
294 | gcov_close (); |
295 | } |
296 | |
297 | static void |
298 | tag_function (const char *filename ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
299 | unsigned tag ATTRIBUTE_UNUSED__attribute__ ((__unused__)), int length, |
300 | unsigned depth ATTRIBUTE_UNUSED__attribute__ ((__unused__))) |
301 | { |
302 | gcov_position_t pos = gcov_position (); |
303 | |
304 | if (!length) |
305 | printf (" placeholder"); |
306 | else |
307 | { |
308 | printf (" ident=%u", gcov_read_unsigned ()); |
309 | printf (", lineno_checksum=0x%08x", gcov_read_unsigned ()); |
310 | printf (", cfg_checksum=0x%08x", gcov_read_unsigned ()); |
311 | |
312 | if (gcov_position () - pos < (gcov_position_t) length) |
313 | { |
314 | const char *name; |
315 | |
316 | name = gcov_read_string (); |
317 | printf (", `%s'", name ? name : "NULL"); |
318 | unsigned artificial = gcov_read_unsigned (); |
319 | name = gcov_read_string (); |
320 | printf (" %s", name ? name : "NULL"); |
321 | unsigned line_start = gcov_read_unsigned (); |
322 | unsigned column_start = gcov_read_unsigned (); |
323 | unsigned line_end = gcov_read_unsigned (); |
324 | unsigned column_end = gcov_read_unsigned (); |
325 | printf (":%u:%u-%u:%u", line_start, column_start, |
326 | line_end, column_end); |
327 | if (artificial) |
328 | printf (", artificial"); |
329 | } |
330 | } |
331 | } |
332 | |
333 | static void |
334 | tag_blocks (const char *filename ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
335 | unsigned tag ATTRIBUTE_UNUSED__attribute__ ((__unused__)), int length ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
336 | unsigned depth ATTRIBUTE_UNUSED__attribute__ ((__unused__))) |
337 | { |
338 | printf (" %u blocks", gcov_read_unsigned ()); |
339 | } |
340 | |
341 | static void |
342 | tag_arcs (const char *filename ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
343 | unsigned tag ATTRIBUTE_UNUSED__attribute__ ((__unused__)), int length ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
344 | unsigned depth) |
345 | { |
346 | unsigned n_arcs = GCOV_TAG_ARCS_NUM (length)(((length) - 1) / 2); |
347 | |
348 | printf (" %u arcs", n_arcs); |
349 | if (flag_dump_contents) |
350 | { |
351 | unsigned ix; |
352 | unsigned blockno = gcov_read_unsigned (); |
353 | |
354 | for (ix = 0; ix != n_arcs; ix++) |
355 | { |
356 | unsigned dst, flags; |
357 | |
358 | if (!(ix & 3)) |
359 | { |
360 | printf ("\n"); |
361 | print_prefix (filename, depth, gcov_position ()); |
362 | printf (VALUE_PADDING_PREFIX" " "block %u:", blockno); |
363 | } |
364 | dst = gcov_read_unsigned (); |
365 | flags = gcov_read_unsigned (); |
366 | printf (" %u:%04x", dst, flags); |
367 | if (flags) |
368 | { |
369 | char c = '('; |
370 | |
371 | if (flags & GCOV_ARC_ON_TREE(1 << 0)) |
372 | printf ("%ctree", c), c = ','; |
373 | if (flags & GCOV_ARC_FAKE(1 << 1)) |
374 | printf ("%cfake", c), c = ','; |
375 | if (flags & GCOV_ARC_FALLTHROUGH(1 << 2)) |
376 | printf ("%cfall", c), c = ','; |
Although the value stored to 'c' is used in the enclosing expression, the value is never actually read from 'c' | |
377 | printf (")"); |
378 | } |
379 | } |
380 | } |
381 | } |
382 | |
383 | static void |
384 | tag_lines (const char *filename ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
385 | unsigned tag ATTRIBUTE_UNUSED__attribute__ ((__unused__)), int length ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
386 | unsigned depth) |
387 | { |
388 | if (flag_dump_contents) |
389 | { |
390 | unsigned blockno = gcov_read_unsigned (); |
391 | char const *sep = NULL__null; |
392 | |
393 | while (1) |
394 | { |
395 | gcov_position_t position = gcov_position (); |
396 | const char *source = NULL__null; |
397 | unsigned lineno = gcov_read_unsigned (); |
398 | |
399 | if (!lineno) |
400 | { |
401 | source = gcov_read_string (); |
402 | if (!source) |
403 | break; |
404 | sep = NULL__null; |
405 | } |
406 | |
407 | if (!sep) |
408 | { |
409 | printf ("\n"); |
410 | print_prefix (filename, depth, position); |
411 | printf (VALUE_PADDING_PREFIX" " "block %u:", blockno); |
412 | sep = ""; |
413 | } |
414 | if (lineno) |
415 | { |
416 | printf ("%s%u", sep, lineno); |
417 | sep = ", "; |
418 | } |
419 | else |
420 | { |
421 | printf ("%s`%s'", sep, source); |
422 | sep = ":"; |
423 | } |
424 | } |
425 | } |
426 | } |
427 | |
428 | static void |
429 | tag_counters (const char *filename ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
430 | unsigned tag ATTRIBUTE_UNUSED__attribute__ ((__unused__)), int length ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
431 | unsigned depth) |
432 | { |
433 | #define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) NAME, |
434 | static const char *const counter_names[] = { |
435 | #include "gcov-counter.def" |
436 | }; |
437 | #undef DEF_GCOV_COUNTER |
438 | int n_counts = GCOV_TAG_COUNTER_NUM (length)((length) / 2); |
439 | bool has_zeros = n_counts < 0; |
440 | n_counts = abs (n_counts); |
441 | |
442 | printf (" %s %u counts%s", |
443 | counter_names[GCOV_COUNTER_FOR_TAG (tag)((unsigned)(((tag) - ((gcov_unsigned_t)0x01a10000)) >> 17 ))], n_counts, |
444 | has_zeros ? " (all zero)" : ""); |
445 | if (flag_dump_contents) |
446 | { |
447 | for (int ix = 0; ix != n_counts; ix++) |
448 | { |
449 | gcov_type count; |
450 | |
451 | if (flag_dump_raw) |
452 | { |
453 | if (ix == 0) |
454 | printf (": "); |
455 | } |
456 | else if (!(ix & 7)) |
457 | { |
458 | printf ("\n"); |
459 | print_prefix (filename, depth, gcov_position ()); |
460 | printf (VALUE_PADDING_PREFIX" " VALUE_PREFIX"%2d: ", ix); |
461 | } |
462 | |
463 | count = has_zeros ? 0 : gcov_read_counter (); |
464 | printf ("%" PRId64"l" "d" " ", count); |
465 | } |
466 | } |
467 | } |
468 | |
469 | static void |
470 | tag_summary (const char *filename ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
471 | unsigned tag ATTRIBUTE_UNUSED__attribute__ ((__unused__)), int length ATTRIBUTE_UNUSED__attribute__ ((__unused__)), |
472 | unsigned depth ATTRIBUTE_UNUSED__attribute__ ((__unused__))) |
473 | { |
474 | gcov_summary summary; |
475 | gcov_read_summary (&summary); |
476 | printf (" runs=%d, sum_max=%" PRId64"l" "d", |
477 | summary.runs, summary.sum_max); |
478 | } |