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