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