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