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