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