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