config.host: Match little-endian powerpc-linux.
[gcc.git] / libgcc / libgcov.c
1 /* Routines required for instrumenting a program. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989-2013 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
25
26 #include "tconfig.h"
27 #include "tsystem.h"
28 #include "coretypes.h"
29 #include "tm.h"
30 #include "libgcc_tm.h"
31 #include "gthr.h"
32
33 #if defined(inhibit_libc)
34 #define IN_LIBGCOV (-1)
35 #else
36 #define IN_LIBGCOV 1
37 #if defined(L_gcov)
38 #define GCOV_LINKAGE /* nothing */
39 #endif
40 #endif
41 #include "gcov-io.h"
42
43 #if defined(inhibit_libc)
44 /* If libc and its header files are not available, provide dummy functions. */
45
46 #ifdef L_gcov
47 void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
48 void __gcov_flush (void) {}
49 #endif
50
51 #ifdef L_gcov_reset
52 void __gcov_reset (void) {}
53 #endif
54
55 #ifdef L_gcov_dump
56 void __gcov_dump (void) {}
57 #endif
58
59 #ifdef L_gcov_merge_add
60 void __gcov_merge_add (gcov_type *counters __attribute__ ((unused)),
61 unsigned n_counters __attribute__ ((unused))) {}
62 #endif
63
64 #ifdef L_gcov_merge_single
65 void __gcov_merge_single (gcov_type *counters __attribute__ ((unused)),
66 unsigned n_counters __attribute__ ((unused))) {}
67 #endif
68
69 #ifdef L_gcov_merge_delta
70 void __gcov_merge_delta (gcov_type *counters __attribute__ ((unused)),
71 unsigned n_counters __attribute__ ((unused))) {}
72 #endif
73
74 #else
75
76 #include <string.h>
77 #if GCOV_LOCKED
78 #include <fcntl.h>
79 #include <errno.h>
80 #include <sys/stat.h>
81 #endif
82
83 extern void gcov_clear (void) ATTRIBUTE_HIDDEN;
84 extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
85 extern int gcov_dump_complete ATTRIBUTE_HIDDEN;
86
87 #ifdef L_gcov
88 #include "gcov-io.c"
89
90 struct gcov_fn_buffer
91 {
92 struct gcov_fn_buffer *next;
93 unsigned fn_ix;
94 struct gcov_fn_info info;
95 /* note gcov_fn_info ends in a trailing array. */
96 };
97
98 struct gcov_summary_buffer
99 {
100 struct gcov_summary_buffer *next;
101 struct gcov_summary summary;
102 };
103
104 /* Chain of per-object gcov structures. */
105 static struct gcov_info *gcov_list;
106
107 /* Size of the longest file name. */
108 static size_t gcov_max_filename = 0;
109
110 /* Flag when the profile has already been dumped via __gcov_dump(). */
111 int gcov_dump_complete = 0;
112
113 /* Make sure path component of the given FILENAME exists, create
114 missing directories. FILENAME must be writable.
115 Returns zero on success, or -1 if an error occurred. */
116
117 static int
118 create_file_directory (char *filename)
119 {
120 #if !defined(TARGET_POSIX_IO) && !defined(_WIN32)
121 (void) filename;
122 return -1;
123 #else
124 char *s;
125
126 s = filename;
127
128 if (HAS_DRIVE_SPEC(s))
129 s += 2;
130 if (IS_DIR_SEPARATOR(*s))
131 ++s;
132 for (; *s != '\0'; s++)
133 if (IS_DIR_SEPARATOR(*s))
134 {
135 char sep = *s;
136 *s = '\0';
137
138 /* Try to make directory if it doesn't already exist. */
139 if (access (filename, F_OK) == -1
140 #ifdef TARGET_POSIX_IO
141 && mkdir (filename, 0755) == -1
142 #else
143 && mkdir (filename) == -1
144 #endif
145 /* The directory might have been made by another process. */
146 && errno != EEXIST)
147 {
148 fprintf (stderr, "profiling:%s:Cannot create directory\n",
149 filename);
150 *s = sep;
151 return -1;
152 };
153
154 *s = sep;
155 };
156 return 0;
157 #endif
158 }
159
160 static struct gcov_fn_buffer *
161 free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
162 unsigned limit)
163 {
164 struct gcov_fn_buffer *next;
165 unsigned ix, n_ctr = 0;
166
167 if (!buffer)
168 return 0;
169 next = buffer->next;
170
171 for (ix = 0; ix != limit; ix++)
172 if (gi_ptr->merge[ix])
173 free (buffer->info.ctrs[n_ctr++].values);
174 free (buffer);
175 return next;
176 }
177
178 static struct gcov_fn_buffer **
179 buffer_fn_data (const char *filename, const struct gcov_info *gi_ptr,
180 struct gcov_fn_buffer **end_ptr, unsigned fn_ix)
181 {
182 unsigned n_ctrs = 0, ix = 0;
183 struct gcov_fn_buffer *fn_buffer;
184 unsigned len;
185
186 for (ix = GCOV_COUNTERS; ix--;)
187 if (gi_ptr->merge[ix])
188 n_ctrs++;
189
190 len = sizeof (*fn_buffer) + sizeof (fn_buffer->info.ctrs[0]) * n_ctrs;
191 fn_buffer = (struct gcov_fn_buffer *)malloc (len);
192
193 if (!fn_buffer)
194 goto fail;
195
196 fn_buffer->next = 0;
197 fn_buffer->fn_ix = fn_ix;
198 fn_buffer->info.ident = gcov_read_unsigned ();
199 fn_buffer->info.lineno_checksum = gcov_read_unsigned ();
200 fn_buffer->info.cfg_checksum = gcov_read_unsigned ();
201
202 for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++)
203 {
204 gcov_unsigned_t length;
205 gcov_type *values;
206
207 if (!gi_ptr->merge[ix])
208 continue;
209
210 if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix))
211 {
212 len = 0;
213 goto fail;
214 }
215
216 length = GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
217 len = length * sizeof (gcov_type);
218 values = (gcov_type *)malloc (len);
219 if (!values)
220 goto fail;
221
222 fn_buffer->info.ctrs[n_ctrs].num = length;
223 fn_buffer->info.ctrs[n_ctrs].values = values;
224
225 while (length--)
226 *values++ = gcov_read_counter ();
227 n_ctrs++;
228 }
229
230 *end_ptr = fn_buffer;
231 return &fn_buffer->next;
232
233 fail:
234 fprintf (stderr, "profiling:%s:Function %u %s %u \n", filename, fn_ix,
235 len ? "cannot allocate" : "counter mismatch", len ? len : ix);
236
237 return (struct gcov_fn_buffer **)free_fn_data (gi_ptr, fn_buffer, ix);
238 }
239
240 /* Add an unsigned value to the current crc */
241
242 static gcov_unsigned_t
243 crc32_unsigned (gcov_unsigned_t crc32, gcov_unsigned_t value)
244 {
245 unsigned ix;
246
247 for (ix = 32; ix--; value <<= 1)
248 {
249 unsigned feedback;
250
251 feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
252 crc32 <<= 1;
253 crc32 ^= feedback;
254 }
255
256 return crc32;
257 }
258
259 /* Check if VERSION of the info block PTR matches libgcov one.
260 Return 1 on success, or zero in case of versions mismatch.
261 If FILENAME is not NULL, its value used for reporting purposes
262 instead of value from the info block. */
263
264 static int
265 gcov_version (struct gcov_info *ptr, gcov_unsigned_t version,
266 const char *filename)
267 {
268 if (version != GCOV_VERSION)
269 {
270 char v[4], e[4];
271
272 GCOV_UNSIGNED2STRING (v, version);
273 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
274
275 fprintf (stderr,
276 "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
277 filename? filename : ptr->filename, e, v);
278 return 0;
279 }
280 return 1;
281 }
282
283 /* Insert counter VALUE into HISTOGRAM. */
284
285 static void
286 gcov_histogram_insert(gcov_bucket_type *histogram, gcov_type value)
287 {
288 unsigned i;
289
290 i = gcov_histo_index(value);
291 histogram[i].num_counters++;
292 histogram[i].cum_value += value;
293 if (value < histogram[i].min_value)
294 histogram[i].min_value = value;
295 }
296
297 /* Computes a histogram of the arc counters to place in the summary SUM. */
298
299 static void
300 gcov_compute_histogram (struct gcov_summary *sum)
301 {
302 struct gcov_info *gi_ptr;
303 const struct gcov_fn_info *gfi_ptr;
304 const struct gcov_ctr_info *ci_ptr;
305 struct gcov_ctr_summary *cs_ptr;
306 unsigned t_ix, f_ix, ctr_info_ix, ix;
307 int h_ix;
308
309 /* This currently only applies to arc counters. */
310 t_ix = GCOV_COUNTER_ARCS;
311
312 /* First check if there are any counts recorded for this counter. */
313 cs_ptr = &(sum->ctrs[t_ix]);
314 if (!cs_ptr->num)
315 return;
316
317 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
318 {
319 cs_ptr->histogram[h_ix].num_counters = 0;
320 cs_ptr->histogram[h_ix].min_value = cs_ptr->run_max;
321 cs_ptr->histogram[h_ix].cum_value = 0;
322 }
323
324 /* Walk through all the per-object structures and record each of
325 the count values in histogram. */
326 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
327 {
328 if (!gi_ptr->merge[t_ix])
329 continue;
330
331 /* Find the appropriate index into the gcov_ctr_info array
332 for the counter we are currently working on based on the
333 existence of the merge function pointer for this object. */
334 for (ix = 0, ctr_info_ix = 0; ix < t_ix; ix++)
335 {
336 if (gi_ptr->merge[ix])
337 ctr_info_ix++;
338 }
339 for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
340 {
341 gfi_ptr = gi_ptr->functions[f_ix];
342
343 if (!gfi_ptr || gfi_ptr->key != gi_ptr)
344 continue;
345
346 ci_ptr = &gfi_ptr->ctrs[ctr_info_ix];
347 for (ix = 0; ix < ci_ptr->num; ix++)
348 gcov_histogram_insert (cs_ptr->histogram, ci_ptr->values[ix]);
349 }
350 }
351 }
352
353 /* Dump the coverage counts. We merge with existing counts when
354 possible, to avoid growing the .da files ad infinitum. We use this
355 program's checksum to make sure we only accumulate whole program
356 statistics to the correct summary. An object file might be embedded
357 in two separate programs, and we must keep the two program
358 summaries separate. */
359
360 void
361 gcov_exit (void)
362 {
363 struct gcov_info *gi_ptr;
364 const struct gcov_fn_info *gfi_ptr;
365 struct gcov_summary this_prg; /* summary for program. */
366 #if !GCOV_LOCKED
367 struct gcov_summary all_prg; /* summary for all instances of program. */
368 #endif
369 struct gcov_ctr_summary *cs_ptr;
370 const struct gcov_ctr_info *ci_ptr;
371 unsigned t_ix;
372 int f_ix;
373 gcov_unsigned_t c_num;
374 const char *gcov_prefix;
375 int gcov_prefix_strip = 0;
376 size_t prefix_length;
377 char *gi_filename, *gi_filename_up;
378 gcov_unsigned_t crc32 = 0;
379
380 /* Prevent the counters from being dumped a second time on exit when the
381 application already wrote out the profile using __gcov_dump(). */
382 if (gcov_dump_complete)
383 return;
384
385 #if !GCOV_LOCKED
386 memset (&all_prg, 0, sizeof (all_prg));
387 #endif
388 /* Find the totals for this execution. */
389 memset (&this_prg, 0, sizeof (this_prg));
390 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
391 {
392 crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
393 crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
394
395 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
396 {
397 gfi_ptr = gi_ptr->functions[f_ix];
398
399 if (gfi_ptr && gfi_ptr->key != gi_ptr)
400 gfi_ptr = 0;
401
402 crc32 = crc32_unsigned (crc32, gfi_ptr ? gfi_ptr->cfg_checksum : 0);
403 crc32 = crc32_unsigned (crc32,
404 gfi_ptr ? gfi_ptr->lineno_checksum : 0);
405 if (!gfi_ptr)
406 continue;
407
408 ci_ptr = gfi_ptr->ctrs;
409 for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
410 {
411 if (!gi_ptr->merge[t_ix])
412 continue;
413
414 cs_ptr = &this_prg.ctrs[t_ix];
415 cs_ptr->num += ci_ptr->num;
416 crc32 = crc32_unsigned (crc32, ci_ptr->num);
417
418 for (c_num = 0; c_num < ci_ptr->num; c_num++)
419 {
420 cs_ptr->sum_all += ci_ptr->values[c_num];
421 if (cs_ptr->run_max < ci_ptr->values[c_num])
422 cs_ptr->run_max = ci_ptr->values[c_num];
423 }
424 ci_ptr++;
425 }
426 }
427 }
428 gcov_compute_histogram (&this_prg);
429
430 {
431 /* Check if the level of dirs to strip off specified. */
432 char *tmp = getenv("GCOV_PREFIX_STRIP");
433 if (tmp)
434 {
435 gcov_prefix_strip = atoi (tmp);
436 /* Do not consider negative values. */
437 if (gcov_prefix_strip < 0)
438 gcov_prefix_strip = 0;
439 }
440 }
441
442 /* Get file name relocation prefix. Non-absolute values are ignored. */
443 gcov_prefix = getenv("GCOV_PREFIX");
444 if (gcov_prefix)
445 {
446 prefix_length = strlen(gcov_prefix);
447
448 /* Remove an unnecessary trailing '/' */
449 if (IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
450 prefix_length--;
451 }
452 else
453 prefix_length = 0;
454
455 /* If no prefix was specified and a prefix stip, then we assume
456 relative. */
457 if (gcov_prefix_strip != 0 && prefix_length == 0)
458 {
459 gcov_prefix = ".";
460 prefix_length = 1;
461 }
462 /* Allocate and initialize the filename scratch space plus one. */
463 gi_filename = (char *) alloca (prefix_length + gcov_max_filename + 2);
464 if (prefix_length)
465 memcpy (gi_filename, gcov_prefix, prefix_length);
466 gi_filename_up = gi_filename + prefix_length;
467
468 /* Now merge each file. */
469 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
470 {
471 unsigned n_counts;
472 struct gcov_summary prg; /* summary for this object over all
473 program. */
474 struct gcov_ctr_summary *cs_prg, *cs_tprg;
475 #if !GCOV_LOCKED
476 struct gcov_ctr_summary *cs_all;
477 #endif
478 int error = 0;
479 gcov_unsigned_t tag, length;
480 gcov_position_t summary_pos = 0;
481 gcov_position_t eof_pos = 0;
482 const char *fname, *s;
483 struct gcov_fn_buffer *fn_buffer = 0;
484 struct gcov_fn_buffer **fn_tail = &fn_buffer;
485 struct gcov_summary_buffer *next_sum_buffer, *sum_buffer = 0;
486 struct gcov_summary_buffer **sum_tail = &sum_buffer;
487
488 fname = gi_ptr->filename;
489
490 /* Avoid to add multiple drive letters into combined path. */
491 if (prefix_length != 0 && HAS_DRIVE_SPEC(fname))
492 fname += 2;
493
494 /* Build relocated filename, stripping off leading
495 directories from the initial filename if requested. */
496 if (gcov_prefix_strip > 0)
497 {
498 int level = 0;
499 s = fname;
500 if (IS_DIR_SEPARATOR(*s))
501 ++s;
502
503 /* Skip selected directory levels. */
504 for (; (*s != '\0') && (level < gcov_prefix_strip); s++)
505 if (IS_DIR_SEPARATOR(*s))
506 {
507 fname = s;
508 level++;
509 }
510 }
511
512 /* Update complete filename with stripped original. */
513 if (prefix_length != 0 && !IS_DIR_SEPARATOR (*fname))
514 {
515 /* If prefix is given, add directory separator. */
516 strcpy (gi_filename_up, "/");
517 strcpy (gi_filename_up + 1, fname);
518 }
519 else
520 strcpy (gi_filename_up, fname);
521
522 if (!gcov_open (gi_filename))
523 {
524 /* Open failed likely due to missed directory.
525 Create directory and retry to open file. */
526 if (create_file_directory (gi_filename))
527 {
528 fprintf (stderr, "profiling:%s:Skip\n", gi_filename);
529 continue;
530 }
531 if (!gcov_open (gi_filename))
532 {
533 fprintf (stderr, "profiling:%s:Cannot open\n", gi_filename);
534 continue;
535 }
536 }
537
538 tag = gcov_read_unsigned ();
539 if (tag)
540 {
541 /* Merge data from file. */
542 if (tag != GCOV_DATA_MAGIC)
543 {
544 fprintf (stderr, "profiling:%s:Not a gcov data file\n",
545 gi_filename);
546 goto read_fatal;
547 }
548 length = gcov_read_unsigned ();
549 if (!gcov_version (gi_ptr, length, gi_filename))
550 goto read_fatal;
551
552 length = gcov_read_unsigned ();
553 if (length != gi_ptr->stamp)
554 /* Read from a different compilation. Overwrite the file. */
555 goto rewrite;
556
557 /* Look for program summary. */
558 for (f_ix = 0;;)
559 {
560 struct gcov_summary tmp;
561
562 eof_pos = gcov_position ();
563 tag = gcov_read_unsigned ();
564 if (tag != GCOV_TAG_PROGRAM_SUMMARY)
565 break;
566
567 f_ix--;
568 length = gcov_read_unsigned ();
569 gcov_read_summary (&tmp);
570 if ((error = gcov_is_error ()))
571 goto read_error;
572 if (summary_pos)
573 {
574 /* Save all summaries after the one that will be
575 merged into below. These will need to be rewritten
576 as histogram merging may change the number of non-zero
577 histogram entries that will be emitted, and thus the
578 size of the merged summary. */
579 (*sum_tail) = (struct gcov_summary_buffer *)
580 malloc (sizeof(struct gcov_summary_buffer));
581 (*sum_tail)->summary = tmp;
582 (*sum_tail)->next = 0;
583 sum_tail = &((*sum_tail)->next);
584 goto next_summary;
585 }
586 if (tmp.checksum != crc32)
587 goto next_summary;
588
589 for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
590 if (tmp.ctrs[t_ix].num != this_prg.ctrs[t_ix].num)
591 goto next_summary;
592 prg = tmp;
593 summary_pos = eof_pos;
594
595 next_summary:;
596 }
597
598 /* Merge execution counts for each function. */
599 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions;
600 f_ix++, tag = gcov_read_unsigned ())
601 {
602 gfi_ptr = gi_ptr->functions[f_ix];
603
604 if (tag != GCOV_TAG_FUNCTION)
605 goto read_mismatch;
606
607 length = gcov_read_unsigned ();
608 if (!length)
609 /* This function did not appear in the other program.
610 We have nothing to merge. */
611 continue;
612
613 if (length != GCOV_TAG_FUNCTION_LENGTH)
614 goto read_mismatch;
615
616 if (!gfi_ptr || gfi_ptr->key != gi_ptr)
617 {
618 /* This function appears in the other program. We
619 need to buffer the information in order to write
620 it back out -- we'll be inserting data before
621 this point, so cannot simply keep the data in the
622 file. */
623 fn_tail = buffer_fn_data (gi_filename,
624 gi_ptr, fn_tail, f_ix);
625 if (!fn_tail)
626 goto read_mismatch;
627 continue;
628 }
629
630 length = gcov_read_unsigned ();
631 if (length != gfi_ptr->ident)
632 goto read_mismatch;
633
634 length = gcov_read_unsigned ();
635 if (length != gfi_ptr->lineno_checksum)
636 goto read_mismatch;
637
638 length = gcov_read_unsigned ();
639 if (length != gfi_ptr->cfg_checksum)
640 goto read_mismatch;
641
642 ci_ptr = gfi_ptr->ctrs;
643 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
644 {
645 gcov_merge_fn merge = gi_ptr->merge[t_ix];
646
647 if (!merge)
648 continue;
649
650 tag = gcov_read_unsigned ();
651 length = gcov_read_unsigned ();
652 if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
653 || length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num))
654 goto read_mismatch;
655 (*merge) (ci_ptr->values, ci_ptr->num);
656 ci_ptr++;
657 }
658 if ((error = gcov_is_error ()))
659 goto read_error;
660 }
661
662 if (tag)
663 {
664 read_mismatch:;
665 fprintf (stderr, "profiling:%s:Merge mismatch for %s %u\n",
666 gi_filename, f_ix >= 0 ? "function" : "summary",
667 f_ix < 0 ? -1 - f_ix : f_ix);
668 goto read_fatal;
669 }
670 }
671 goto rewrite;
672
673 read_error:;
674 fprintf (stderr, "profiling:%s:%s merging\n", gi_filename,
675 error < 0 ? "Overflow": "Error");
676
677 goto read_fatal;
678
679 rewrite:;
680 gcov_rewrite ();
681 if (!summary_pos)
682 {
683 memset (&prg, 0, sizeof (prg));
684 summary_pos = eof_pos;
685 }
686
687 /* Merge the summaries. */
688 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
689 {
690 cs_prg = &prg.ctrs[t_ix];
691 cs_tprg = &this_prg.ctrs[t_ix];
692
693 if (gi_ptr->merge[t_ix])
694 {
695 if (!cs_prg->runs++)
696 cs_prg->num = cs_tprg->num;
697 cs_prg->sum_all += cs_tprg->sum_all;
698 if (cs_prg->run_max < cs_tprg->run_max)
699 cs_prg->run_max = cs_tprg->run_max;
700 cs_prg->sum_max += cs_tprg->run_max;
701 if (cs_prg->runs == 1)
702 memcpy (cs_prg->histogram, cs_tprg->histogram,
703 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
704 else
705 gcov_histogram_merge (cs_prg->histogram, cs_tprg->histogram);
706 }
707 else if (cs_prg->runs)
708 goto read_mismatch;
709
710 #if !GCOV_LOCKED
711 cs_all = &all_prg.ctrs[t_ix];
712 if (!cs_all->runs && cs_prg->runs)
713 {
714 cs_all->num = cs_prg->num;
715 cs_all->runs = cs_prg->runs;
716 cs_all->sum_all = cs_prg->sum_all;
717 cs_all->run_max = cs_prg->run_max;
718 cs_all->sum_max = cs_prg->sum_max;
719 }
720 else if (!all_prg.checksum
721 /* Don't compare the histograms, which may have slight
722 variations depending on the order they were updated
723 due to the truncating integer divides used in the
724 merge. */
725 && (cs_all->num != cs_prg->num
726 || cs_all->runs != cs_prg->runs
727 || cs_all->sum_all != cs_prg->sum_all
728 || cs_all->run_max != cs_prg->run_max
729 || cs_all->sum_max != cs_prg->sum_max))
730 {
731 fprintf (stderr,
732 "profiling:%s:Data file mismatch - some data files may "
733 "have been concurrently updated without locking support\n",
734 gi_filename);
735 all_prg.checksum = ~0u;
736 }
737 #endif
738 }
739
740 prg.checksum = crc32;
741
742 /* Write out the data. */
743 if (!eof_pos)
744 {
745 gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
746 gcov_write_unsigned (gi_ptr->stamp);
747 }
748
749 if (summary_pos)
750 gcov_seek (summary_pos);
751
752 /* Generate whole program statistics. */
753 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &prg);
754
755 /* Rewrite all the summaries that were after the summary we merged
756 into. This is necessary as the merged summary may have a different
757 size due to the number of non-zero histogram entries changing after
758 merging. */
759
760 while (sum_buffer)
761 {
762 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &sum_buffer->summary);
763 next_sum_buffer = sum_buffer->next;
764 free (sum_buffer);
765 sum_buffer = next_sum_buffer;
766 }
767
768 /* Write execution counts for each function. */
769 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
770 {
771 unsigned buffered = 0;
772
773 if (fn_buffer && fn_buffer->fn_ix == (unsigned)f_ix)
774 {
775 /* Buffered data from another program. */
776 buffered = 1;
777 gfi_ptr = &fn_buffer->info;
778 length = GCOV_TAG_FUNCTION_LENGTH;
779 }
780 else
781 {
782 gfi_ptr = gi_ptr->functions[f_ix];
783 if (gfi_ptr && gfi_ptr->key == gi_ptr)
784 length = GCOV_TAG_FUNCTION_LENGTH;
785 else
786 length = 0;
787 }
788
789 gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
790 if (!length)
791 continue;
792
793 gcov_write_unsigned (gfi_ptr->ident);
794 gcov_write_unsigned (gfi_ptr->lineno_checksum);
795 gcov_write_unsigned (gfi_ptr->cfg_checksum);
796
797 ci_ptr = gfi_ptr->ctrs;
798 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
799 {
800 if (!gi_ptr->merge[t_ix])
801 continue;
802
803 n_counts = ci_ptr->num;
804 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
805 GCOV_TAG_COUNTER_LENGTH (n_counts));
806 gcov_type *c_ptr = ci_ptr->values;
807 while (n_counts--)
808 gcov_write_counter (*c_ptr++);
809 ci_ptr++;
810 }
811 if (buffered)
812 fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
813 }
814
815 gcov_write_unsigned (0);
816
817 read_fatal:;
818 while (fn_buffer)
819 fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
820
821 if ((error = gcov_close ()))
822 fprintf (stderr, error < 0 ?
823 "profiling:%s:Overflow writing\n" :
824 "profiling:%s:Error writing\n",
825 gi_filename);
826 }
827 }
828
829 /* Reset all counters to zero. */
830
831 void
832 gcov_clear (void)
833 {
834 const struct gcov_info *gi_ptr;
835
836 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
837 {
838 unsigned f_ix;
839
840 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
841 {
842 unsigned t_ix;
843 const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
844
845 if (!gfi_ptr || gfi_ptr->key != gi_ptr)
846 continue;
847 const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
848 for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
849 {
850 if (!gi_ptr->merge[t_ix])
851 continue;
852
853 memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
854 ci_ptr++;
855 }
856 }
857 }
858 }
859
860 /* Add a new object file onto the bb chain. Invoked automatically
861 when running an object file's global ctors. */
862
863 void
864 __gcov_init (struct gcov_info *info)
865 {
866 if (!info->version || !info->n_functions)
867 return;
868 if (gcov_version (info, info->version, 0))
869 {
870 size_t filename_length = strlen(info->filename);
871
872 /* Refresh the longest file name information */
873 if (filename_length > gcov_max_filename)
874 gcov_max_filename = filename_length;
875
876 if (!gcov_list)
877 atexit (gcov_exit);
878
879 info->next = gcov_list;
880 gcov_list = info;
881 }
882 info->version = 0;
883 }
884
885 #ifdef __GTHREAD_MUTEX_INIT
886 ATTRIBUTE_HIDDEN __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
887 #define init_mx_once()
888 #else
889 __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
890
891 static void
892 init_mx (void)
893 {
894 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
895 }
896 static void
897 init_mx_once (void)
898 {
899 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
900 __gthread_once (&once, init_mx);
901 }
902 #endif
903
904 /* Called before fork or exec - write out profile information gathered so
905 far and reset it to zero. This avoids duplication or loss of the
906 profile information gathered so far. */
907
908 void
909 __gcov_flush (void)
910 {
911 init_mx_once ();
912 __gthread_mutex_lock (&__gcov_flush_mx);
913
914 gcov_exit ();
915 gcov_clear ();
916
917 __gthread_mutex_unlock (&__gcov_flush_mx);
918 }
919
920 #endif /* L_gcov */
921
922 #ifdef L_gcov_reset
923
924 /* Function that can be called from application to reset counters to zero,
925 in order to collect profile in region of interest. */
926
927 void
928 __gcov_reset (void)
929 {
930 gcov_clear ();
931 /* Re-enable dumping to support collecting profile in multiple regions
932 of interest. */
933 gcov_dump_complete = 0;
934 }
935
936 #endif /* L_gcov_reset */
937
938 #ifdef L_gcov_dump
939
940 /* Function that can be called from application to write profile collected
941 so far, in order to collect profile in region of interest. */
942
943 void
944 __gcov_dump (void)
945 {
946 gcov_exit ();
947 /* Prevent profile from being dumped a second time on application exit. */
948 gcov_dump_complete = 1;
949 }
950
951 #endif /* L_gcov_dump */
952
953 #ifdef L_gcov_merge_add
954 /* The profile merging function that just adds the counters. It is given
955 an array COUNTERS of N_COUNTERS old counters and it reads the same number
956 of counters from the gcov file. */
957 void
958 __gcov_merge_add (gcov_type *counters, unsigned n_counters)
959 {
960 for (; n_counters; counters++, n_counters--)
961 *counters += gcov_read_counter ();
962 }
963 #endif /* L_gcov_merge_add */
964
965 #ifdef L_gcov_merge_ior
966 /* The profile merging function that just adds the counters. It is given
967 an array COUNTERS of N_COUNTERS old counters and it reads the same number
968 of counters from the gcov file. */
969 void
970 __gcov_merge_ior (gcov_type *counters, unsigned n_counters)
971 {
972 for (; n_counters; counters++, n_counters--)
973 *counters |= gcov_read_counter ();
974 }
975 #endif
976
977 #ifdef L_gcov_merge_single
978 /* The profile merging function for choosing the most common value.
979 It is given an array COUNTERS of N_COUNTERS old counters and it
980 reads the same number of counters from the gcov file. The counters
981 are split into 3-tuples where the members of the tuple have
982 meanings:
983
984 -- the stored candidate on the most common value of the measured entity
985 -- counter
986 -- total number of evaluations of the value */
987 void
988 __gcov_merge_single (gcov_type *counters, unsigned n_counters)
989 {
990 unsigned i, n_measures;
991 gcov_type value, counter, all;
992
993 gcc_assert (!(n_counters % 3));
994 n_measures = n_counters / 3;
995 for (i = 0; i < n_measures; i++, counters += 3)
996 {
997 value = gcov_read_counter ();
998 counter = gcov_read_counter ();
999 all = gcov_read_counter ();
1000
1001 if (counters[0] == value)
1002 counters[1] += counter;
1003 else if (counter > counters[1])
1004 {
1005 counters[0] = value;
1006 counters[1] = counter - counters[1];
1007 }
1008 else
1009 counters[1] -= counter;
1010 counters[2] += all;
1011 }
1012 }
1013 #endif /* L_gcov_merge_single */
1014
1015 #ifdef L_gcov_merge_delta
1016 /* The profile merging function for choosing the most common
1017 difference between two consecutive evaluations of the value. It is
1018 given an array COUNTERS of N_COUNTERS old counters and it reads the
1019 same number of counters from the gcov file. The counters are split
1020 into 4-tuples where the members of the tuple have meanings:
1021
1022 -- the last value of the measured entity
1023 -- the stored candidate on the most common difference
1024 -- counter
1025 -- total number of evaluations of the value */
1026 void
1027 __gcov_merge_delta (gcov_type *counters, unsigned n_counters)
1028 {
1029 unsigned i, n_measures;
1030 gcov_type value, counter, all;
1031
1032 gcc_assert (!(n_counters % 4));
1033 n_measures = n_counters / 4;
1034 for (i = 0; i < n_measures; i++, counters += 4)
1035 {
1036 /* last = */ gcov_read_counter ();
1037 value = gcov_read_counter ();
1038 counter = gcov_read_counter ();
1039 all = gcov_read_counter ();
1040
1041 if (counters[1] == value)
1042 counters[2] += counter;
1043 else if (counter > counters[2])
1044 {
1045 counters[1] = value;
1046 counters[2] = counter - counters[2];
1047 }
1048 else
1049 counters[2] -= counter;
1050 counters[3] += all;
1051 }
1052 }
1053 #endif /* L_gcov_merge_delta */
1054
1055 #ifdef L_gcov_interval_profiler
1056 /* If VALUE is in interval <START, START + STEPS - 1>, then increases the
1057 corresponding counter in COUNTERS. If the VALUE is above or below
1058 the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
1059 instead. */
1060
1061 void
1062 __gcov_interval_profiler (gcov_type *counters, gcov_type value,
1063 int start, unsigned steps)
1064 {
1065 gcov_type delta = value - start;
1066 if (delta < 0)
1067 counters[steps + 1]++;
1068 else if (delta >= steps)
1069 counters[steps]++;
1070 else
1071 counters[delta]++;
1072 }
1073 #endif
1074
1075 #ifdef L_gcov_pow2_profiler
1076 /* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
1077 COUNTERS[0] is incremented. */
1078
1079 void
1080 __gcov_pow2_profiler (gcov_type *counters, gcov_type value)
1081 {
1082 if (value & (value - 1))
1083 counters[0]++;
1084 else
1085 counters[1]++;
1086 }
1087 #endif
1088
1089 /* Tries to determine the most common value among its inputs. Checks if the
1090 value stored in COUNTERS[0] matches VALUE. If this is the case, COUNTERS[1]
1091 is incremented. If this is not the case and COUNTERS[1] is not zero,
1092 COUNTERS[1] is decremented. Otherwise COUNTERS[1] is set to one and
1093 VALUE is stored to COUNTERS[0]. This algorithm guarantees that if this
1094 function is called more than 50% of the time with one value, this value
1095 will be in COUNTERS[0] in the end.
1096
1097 In any case, COUNTERS[2] is incremented. */
1098
1099 static inline void
1100 __gcov_one_value_profiler_body (gcov_type *counters, gcov_type value)
1101 {
1102 if (value == counters[0])
1103 counters[1]++;
1104 else if (counters[1] == 0)
1105 {
1106 counters[1] = 1;
1107 counters[0] = value;
1108 }
1109 else
1110 counters[1]--;
1111 counters[2]++;
1112 }
1113
1114 #ifdef L_gcov_one_value_profiler
1115 void
1116 __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
1117 {
1118 __gcov_one_value_profiler_body (counters, value);
1119 }
1120 #endif
1121
1122 #ifdef L_gcov_indirect_call_profiler
1123
1124 /* By default, the C++ compiler will use function addresses in the
1125 vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
1126 tells the compiler to use function descriptors instead. The value
1127 of this macro says how many words wide the descriptor is (normally 2),
1128 but it may be dependent on target flags. Since we do not have access
1129 to the target flags here we just check to see if it is set and use
1130 that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
1131
1132 It is assumed that the address of a function descriptor may be treated
1133 as a pointer to a function. */
1134
1135 #ifdef TARGET_VTABLE_USES_DESCRIPTORS
1136 #define VTABLE_USES_DESCRIPTORS 1
1137 #else
1138 #define VTABLE_USES_DESCRIPTORS 0
1139 #endif
1140
1141 /* Tries to determine the most common value among its inputs. */
1142 void
1143 __gcov_indirect_call_profiler (gcov_type* counter, gcov_type value,
1144 void* cur_func, void* callee_func)
1145 {
1146 /* If the C++ virtual tables contain function descriptors then one
1147 function may have multiple descriptors and we need to dereference
1148 the descriptors to see if they point to the same function. */
1149 if (cur_func == callee_func
1150 || (VTABLE_USES_DESCRIPTORS && callee_func
1151 && *(void **) cur_func == *(void **) callee_func))
1152 __gcov_one_value_profiler_body (counter, value);
1153 }
1154 #endif
1155
1156
1157 #ifdef L_gcov_average_profiler
1158 /* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
1159 to saturate up. */
1160
1161 void
1162 __gcov_average_profiler (gcov_type *counters, gcov_type value)
1163 {
1164 counters[0] += value;
1165 counters[1] ++;
1166 }
1167 #endif
1168
1169 #ifdef L_gcov_ior_profiler
1170 /* Bitwise-OR VALUE into COUNTER. */
1171
1172 void
1173 __gcov_ior_profiler (gcov_type *counters, gcov_type value)
1174 {
1175 *counters |= value;
1176 }
1177 #endif
1178
1179 #ifdef L_gcov_fork
1180 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
1181 that they are not counted twice. */
1182
1183 pid_t
1184 __gcov_fork (void)
1185 {
1186 pid_t pid;
1187 extern __gthread_mutex_t __gcov_flush_mx;
1188 __gcov_flush ();
1189 pid = fork ();
1190 if (pid == 0)
1191 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
1192 return pid;
1193 }
1194 #endif
1195
1196 #ifdef L_gcov_execl
1197 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
1198 that they are not lost. */
1199
1200 int
1201 __gcov_execl (const char *path, char *arg, ...)
1202 {
1203 va_list ap, aq;
1204 unsigned i, length;
1205 char **args;
1206
1207 __gcov_flush ();
1208
1209 va_start (ap, arg);
1210 va_copy (aq, ap);
1211
1212 length = 2;
1213 while (va_arg (ap, char *))
1214 length++;
1215 va_end (ap);
1216
1217 args = (char **) alloca (length * sizeof (void *));
1218 args[0] = arg;
1219 for (i = 1; i < length; i++)
1220 args[i] = va_arg (aq, char *);
1221 va_end (aq);
1222
1223 return execv (path, args);
1224 }
1225 #endif
1226
1227 #ifdef L_gcov_execlp
1228 /* A wrapper for the execlp function. Flushes the accumulated profiling data, so
1229 that they are not lost. */
1230
1231 int
1232 __gcov_execlp (const char *path, char *arg, ...)
1233 {
1234 va_list ap, aq;
1235 unsigned i, length;
1236 char **args;
1237
1238 __gcov_flush ();
1239
1240 va_start (ap, arg);
1241 va_copy (aq, ap);
1242
1243 length = 2;
1244 while (va_arg (ap, char *))
1245 length++;
1246 va_end (ap);
1247
1248 args = (char **) alloca (length * sizeof (void *));
1249 args[0] = arg;
1250 for (i = 1; i < length; i++)
1251 args[i] = va_arg (aq, char *);
1252 va_end (aq);
1253
1254 return execvp (path, args);
1255 }
1256 #endif
1257
1258 #ifdef L_gcov_execle
1259 /* A wrapper for the execle function. Flushes the accumulated profiling data, so
1260 that they are not lost. */
1261
1262 int
1263 __gcov_execle (const char *path, char *arg, ...)
1264 {
1265 va_list ap, aq;
1266 unsigned i, length;
1267 char **args;
1268 char **envp;
1269
1270 __gcov_flush ();
1271
1272 va_start (ap, arg);
1273 va_copy (aq, ap);
1274
1275 length = 2;
1276 while (va_arg (ap, char *))
1277 length++;
1278 va_end (ap);
1279
1280 args = (char **) alloca (length * sizeof (void *));
1281 args[0] = arg;
1282 for (i = 1; i < length; i++)
1283 args[i] = va_arg (aq, char *);
1284 envp = va_arg (aq, char **);
1285 va_end (aq);
1286
1287 return execve (path, args, envp);
1288 }
1289 #endif
1290
1291 #ifdef L_gcov_execv
1292 /* A wrapper for the execv function. Flushes the accumulated profiling data, so
1293 that they are not lost. */
1294
1295 int
1296 __gcov_execv (const char *path, char *const argv[])
1297 {
1298 __gcov_flush ();
1299 return execv (path, argv);
1300 }
1301 #endif
1302
1303 #ifdef L_gcov_execvp
1304 /* A wrapper for the execvp function. Flushes the accumulated profiling data, so
1305 that they are not lost. */
1306
1307 int
1308 __gcov_execvp (const char *path, char *const argv[])
1309 {
1310 __gcov_flush ();
1311 return execvp (path, argv);
1312 }
1313 #endif
1314
1315 #ifdef L_gcov_execve
1316 /* A wrapper for the execve function. Flushes the accumulated profiling data, so
1317 that they are not lost. */
1318
1319 int
1320 __gcov_execve (const char *path, char *const argv[], char *const envp[])
1321 {
1322 __gcov_flush ();
1323 return execve (path, argv, envp);
1324 }
1325 #endif
1326 #endif /* inhibit_libc */