[NDS32] Support Linux target for nds32.
[official-gcc.git] / libgcc / libgcov-driver.c
blob610356383f1541461ebd7ca545f11667d2824963
1 /* Routines required for instrumenting a program. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989-2018 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
26 #include "libgcov.h"
28 #if defined(inhibit_libc)
29 /* If libc and its header files are not available, provide dummy functions. */
31 #if defined(L_gcov)
32 void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
33 #endif
35 #else /* inhibit_libc */
37 #include <string.h>
38 #if GCOV_LOCKED
39 #include <fcntl.h>
40 #include <errno.h>
41 #include <sys/stat.h>
42 #endif
44 #ifdef L_gcov
46 /* A utility function for outputting errors. */
47 static int gcov_error (const char *, ...);
49 #if !IN_GCOV_TOOL
50 static void gcov_error_exit (void);
51 #endif
53 #include "gcov-io.c"
55 struct gcov_fn_buffer
57 struct gcov_fn_buffer *next;
58 unsigned fn_ix;
59 struct gcov_fn_info info;
60 /* note gcov_fn_info ends in a trailing array. */
63 struct gcov_summary_buffer
65 struct gcov_summary_buffer *next;
66 struct gcov_summary summary;
69 /* A struct that bundles all the related information about the
70 gcda filename. */
72 struct gcov_filename
74 char *filename; /* filename buffer */
75 size_t max_length; /* maximum filename length */
76 int strip; /* leading chars to strip from filename */
77 size_t prefix; /* chars to prepend to filename */
80 static struct gcov_fn_buffer *
81 free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
82 unsigned limit)
84 struct gcov_fn_buffer *next;
85 unsigned ix, n_ctr = 0;
87 if (!buffer)
88 return 0;
89 next = buffer->next;
91 for (ix = 0; ix != limit; ix++)
92 if (gi_ptr->merge[ix])
93 free (buffer->info.ctrs[n_ctr++].values);
94 free (buffer);
95 return next;
98 static struct gcov_fn_buffer **
99 buffer_fn_data (const char *filename, const struct gcov_info *gi_ptr,
100 struct gcov_fn_buffer **end_ptr, unsigned fn_ix)
102 unsigned n_ctrs = 0, ix = 0;
103 struct gcov_fn_buffer *fn_buffer;
104 unsigned len;
106 for (ix = GCOV_COUNTERS; ix--;)
107 if (gi_ptr->merge[ix])
108 n_ctrs++;
110 len = sizeof (*fn_buffer) + sizeof (fn_buffer->info.ctrs[0]) * n_ctrs;
111 fn_buffer = (struct gcov_fn_buffer *) xmalloc (len);
113 if (!fn_buffer)
114 goto fail;
116 fn_buffer->next = 0;
117 fn_buffer->fn_ix = fn_ix;
118 fn_buffer->info.ident = gcov_read_unsigned ();
119 fn_buffer->info.lineno_checksum = gcov_read_unsigned ();
120 fn_buffer->info.cfg_checksum = gcov_read_unsigned ();
122 for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++)
124 gcov_unsigned_t length;
125 gcov_type *values;
127 if (!gi_ptr->merge[ix])
128 continue;
130 if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix))
132 len = 0;
133 goto fail;
136 length = GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
137 len = length * sizeof (gcov_type);
138 values = (gcov_type *) xmalloc (len);
139 if (!values)
140 goto fail;
142 fn_buffer->info.ctrs[n_ctrs].num = length;
143 fn_buffer->info.ctrs[n_ctrs].values = values;
145 while (length--)
146 *values++ = gcov_read_counter ();
147 n_ctrs++;
150 *end_ptr = fn_buffer;
151 return &fn_buffer->next;
153 fail:
154 gcov_error ("profiling:%s:Function %u %s %u \n", filename, fn_ix,
155 len ? "cannot allocate" : "counter mismatch", len ? len : ix);
157 return (struct gcov_fn_buffer **)free_fn_data (gi_ptr, fn_buffer, ix);
160 /* Add an unsigned value to the current crc */
162 static gcov_unsigned_t
163 crc32_unsigned (gcov_unsigned_t crc32, gcov_unsigned_t value)
165 unsigned ix;
167 for (ix = 32; ix--; value <<= 1)
169 unsigned feedback;
171 feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
172 crc32 <<= 1;
173 crc32 ^= feedback;
176 return crc32;
179 /* Check if VERSION of the info block PTR matches libgcov one.
180 Return 1 on success, or zero in case of versions mismatch.
181 If FILENAME is not NULL, its value used for reporting purposes
182 instead of value from the info block. */
184 static int
185 gcov_version (struct gcov_info *ptr, gcov_unsigned_t version,
186 const char *filename)
188 if (version != GCOV_VERSION)
190 char v[4], e[4];
192 GCOV_UNSIGNED2STRING (v, version);
193 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
195 gcov_error ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
196 filename? filename : ptr->filename, e, v);
197 return 0;
199 return 1;
202 /* Insert counter VALUE into HISTOGRAM. */
204 static void
205 gcov_histogram_insert(gcov_bucket_type *histogram, gcov_type value)
207 unsigned i;
209 i = gcov_histo_index(value);
210 histogram[i].num_counters++;
211 histogram[i].cum_value += value;
212 if (value < histogram[i].min_value)
213 histogram[i].min_value = value;
216 /* Computes a histogram of the arc counters to place in the summary SUM. */
218 static void
219 gcov_compute_histogram (struct gcov_info *list, struct gcov_summary *sum)
221 struct gcov_info *gi_ptr;
222 const struct gcov_fn_info *gfi_ptr;
223 const struct gcov_ctr_info *ci_ptr;
224 struct gcov_ctr_summary *cs_ptr;
225 unsigned t_ix, f_ix, ctr_info_ix, ix;
226 int h_ix;
228 /* This currently only applies to arc counters. */
229 t_ix = GCOV_COUNTER_ARCS;
231 /* First check if there are any counts recorded for this counter. */
232 cs_ptr = &(sum->ctrs[t_ix]);
233 if (!cs_ptr->num)
234 return;
236 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
238 cs_ptr->histogram[h_ix].num_counters = 0;
239 cs_ptr->histogram[h_ix].min_value = cs_ptr->run_max;
240 cs_ptr->histogram[h_ix].cum_value = 0;
243 /* Walk through all the per-object structures and record each of
244 the count values in histogram. */
245 for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
247 if (!gi_ptr->merge[t_ix])
248 continue;
250 /* Find the appropriate index into the gcov_ctr_info array
251 for the counter we are currently working on based on the
252 existence of the merge function pointer for this object. */
253 for (ix = 0, ctr_info_ix = 0; ix < t_ix; ix++)
255 if (gi_ptr->merge[ix])
256 ctr_info_ix++;
258 for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
260 gfi_ptr = gi_ptr->functions[f_ix];
262 if (!gfi_ptr || gfi_ptr->key != gi_ptr)
263 continue;
265 ci_ptr = &gfi_ptr->ctrs[ctr_info_ix];
266 for (ix = 0; ix < ci_ptr->num; ix++)
267 gcov_histogram_insert (cs_ptr->histogram, ci_ptr->values[ix]);
272 /* buffer for the fn_data from another program. */
273 static struct gcov_fn_buffer *fn_buffer;
274 /* buffer for summary from other programs to be written out. */
275 static struct gcov_summary_buffer *sum_buffer;
277 /* This function computes the program level summary and the histo-gram.
278 It computes and returns CRC32 and stored summary in THIS_PRG.
279 Also determines the longest filename length of the info files. */
281 #if !IN_GCOV_TOOL
282 static
283 #endif
284 gcov_unsigned_t
285 compute_summary (struct gcov_info *list, struct gcov_summary *this_prg,
286 size_t *max_length)
288 struct gcov_info *gi_ptr;
289 const struct gcov_fn_info *gfi_ptr;
290 struct gcov_ctr_summary *cs_ptr;
291 const struct gcov_ctr_info *ci_ptr;
292 int f_ix;
293 unsigned t_ix;
294 gcov_unsigned_t c_num;
295 gcov_unsigned_t crc32 = 0;
297 /* Find the totals for this execution. */
298 memset (this_prg, 0, sizeof (*this_prg));
299 *max_length = 0;
300 for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
302 size_t len = strlen (gi_ptr->filename);
303 if (len > *max_length)
304 *max_length = len;
306 crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
307 crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
309 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
311 gfi_ptr = gi_ptr->functions[f_ix];
313 if (gfi_ptr && gfi_ptr->key != gi_ptr)
314 gfi_ptr = 0;
316 crc32 = crc32_unsigned (crc32, gfi_ptr ? gfi_ptr->cfg_checksum : 0);
317 crc32 = crc32_unsigned (crc32,
318 gfi_ptr ? gfi_ptr->lineno_checksum : 0);
319 if (!gfi_ptr)
320 continue;
322 ci_ptr = gfi_ptr->ctrs;
323 for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
325 if (!gi_ptr->merge[t_ix])
326 continue;
328 cs_ptr = &(this_prg->ctrs[t_ix]);
329 cs_ptr->num += ci_ptr->num;
330 crc32 = crc32_unsigned (crc32, ci_ptr->num);
332 for (c_num = 0; c_num < ci_ptr->num; c_num++)
334 cs_ptr->sum_all += ci_ptr->values[c_num];
335 if (cs_ptr->run_max < ci_ptr->values[c_num])
336 cs_ptr->run_max = ci_ptr->values[c_num];
338 ci_ptr++;
342 gcov_compute_histogram (list, this_prg);
343 return crc32;
346 /* Including system dependent components. */
347 #include "libgcov-driver-system.c"
349 /* This function merges counters in GI_PTR to an existing gcda file.
350 Return 0 on success.
351 Return -1 on error. In this case, caller will goto read_fatal. */
353 static int
354 merge_one_data (const char *filename,
355 struct gcov_info *gi_ptr,
356 struct gcov_summary *prg_p,
357 struct gcov_summary *this_prg,
358 gcov_position_t *summary_pos_p,
359 gcov_position_t *eof_pos_p,
360 gcov_unsigned_t crc32)
362 gcov_unsigned_t tag, length;
363 unsigned t_ix;
364 int f_ix;
365 int error = 0;
366 struct gcov_fn_buffer **fn_tail = &fn_buffer;
367 struct gcov_summary_buffer **sum_tail = &sum_buffer;
369 length = gcov_read_unsigned ();
370 if (!gcov_version (gi_ptr, length, filename))
371 return -1;
373 length = gcov_read_unsigned ();
374 if (length != gi_ptr->stamp)
376 /* Read from a different compilation. Overwrite the file. */
377 gcov_error ("profiling:%s:overwriting an existing profile data "
378 "with a different timestamp\n", filename);
379 return 0;
382 /* Look for program summary. */
383 for (f_ix = 0;;)
385 struct gcov_summary tmp;
387 *eof_pos_p = gcov_position ();
388 tag = gcov_read_unsigned ();
389 if (tag != GCOV_TAG_PROGRAM_SUMMARY)
390 break;
392 f_ix--;
393 length = gcov_read_unsigned ();
394 gcov_read_summary (&tmp);
395 if ((error = gcov_is_error ()))
396 goto read_error;
397 if (*summary_pos_p)
399 /* Save all summaries after the one that will be
400 merged into below. These will need to be rewritten
401 as histogram merging may change the number of non-zero
402 histogram entries that will be emitted, and thus the
403 size of the merged summary. */
404 (*sum_tail) = (struct gcov_summary_buffer *)
405 xmalloc (sizeof(struct gcov_summary_buffer));
406 (*sum_tail)->summary = tmp;
407 (*sum_tail)->next = 0;
408 sum_tail = &((*sum_tail)->next);
409 goto next_summary;
411 if (tmp.checksum != crc32)
412 goto next_summary;
414 for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
415 if (tmp.ctrs[t_ix].num != this_prg->ctrs[t_ix].num)
416 goto next_summary;
417 *prg_p = tmp;
418 *summary_pos_p = *eof_pos_p;
420 next_summary:;
423 /* Merge execution counts for each function. */
424 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions;
425 f_ix++, tag = gcov_read_unsigned ())
427 const struct gcov_ctr_info *ci_ptr;
428 const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
430 if (tag != GCOV_TAG_FUNCTION)
431 goto read_mismatch;
433 length = gcov_read_unsigned ();
434 if (!length)
435 /* This function did not appear in the other program.
436 We have nothing to merge. */
437 continue;
439 if (length != GCOV_TAG_FUNCTION_LENGTH)
440 goto read_mismatch;
442 if (!gfi_ptr || gfi_ptr->key != gi_ptr)
444 /* This function appears in the other program. We
445 need to buffer the information in order to write
446 it back out -- we'll be inserting data before
447 this point, so cannot simply keep the data in the
448 file. */
449 fn_tail = buffer_fn_data (filename, gi_ptr, fn_tail, f_ix);
450 if (!fn_tail)
451 goto read_mismatch;
452 continue;
455 length = gcov_read_unsigned ();
456 if (length != gfi_ptr->ident)
457 goto read_mismatch;
459 length = gcov_read_unsigned ();
460 if (length != gfi_ptr->lineno_checksum)
461 goto read_mismatch;
463 length = gcov_read_unsigned ();
464 if (length != gfi_ptr->cfg_checksum)
465 goto read_mismatch;
467 ci_ptr = gfi_ptr->ctrs;
468 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
470 gcov_merge_fn merge = gi_ptr->merge[t_ix];
472 if (!merge)
473 continue;
475 tag = gcov_read_unsigned ();
476 length = gcov_read_unsigned ();
477 if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
478 || length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num))
479 goto read_mismatch;
480 (*merge) (ci_ptr->values, ci_ptr->num);
481 ci_ptr++;
483 if ((error = gcov_is_error ()))
484 goto read_error;
487 if (tag)
489 read_mismatch:;
490 gcov_error ("profiling:%s:Merge mismatch for %s %u\n",
491 filename, f_ix >= 0 ? "function" : "summary",
492 f_ix < 0 ? -1 - f_ix : f_ix);
493 return -1;
495 return 0;
497 read_error:
498 gcov_error ("profiling:%s:%s merging\n", filename,
499 error < 0 ? "Overflow": "Error");
500 return -1;
503 /* Write counters in GI_PTR and the summary in PRG to a gcda file. In
504 the case of appending to an existing file, SUMMARY_POS will be non-zero.
505 We will write the file starting from SUMMAY_POS. */
507 static void
508 write_one_data (const struct gcov_info *gi_ptr,
509 const struct gcov_summary *prg_p,
510 const gcov_position_t eof_pos,
511 const gcov_position_t summary_pos)
513 unsigned f_ix;
514 struct gcov_summary_buffer *next_sum_buffer;
516 /* Write out the data. */
517 if (!eof_pos)
519 gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
520 gcov_write_unsigned (gi_ptr->stamp);
523 if (summary_pos)
524 gcov_seek (summary_pos);
526 /* Generate whole program statistics. */
527 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, prg_p);
529 /* Rewrite all the summaries that were after the summary we merged
530 into. This is necessary as the merged summary may have a different
531 size due to the number of non-zero histogram entries changing after
532 merging. */
534 while (sum_buffer)
536 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &sum_buffer->summary);
537 next_sum_buffer = sum_buffer->next;
538 free (sum_buffer);
539 sum_buffer = next_sum_buffer;
542 /* Write execution counts for each function. */
543 for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
545 unsigned buffered = 0;
546 const struct gcov_fn_info *gfi_ptr;
547 const struct gcov_ctr_info *ci_ptr;
548 gcov_unsigned_t length;
549 unsigned t_ix;
551 if (fn_buffer && fn_buffer->fn_ix == f_ix)
553 /* Buffered data from another program. */
554 buffered = 1;
555 gfi_ptr = &fn_buffer->info;
556 length = GCOV_TAG_FUNCTION_LENGTH;
558 else
560 gfi_ptr = gi_ptr->functions[f_ix];
561 if (gfi_ptr && gfi_ptr->key == gi_ptr)
562 length = GCOV_TAG_FUNCTION_LENGTH;
563 else
564 length = 0;
567 gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
568 if (!length)
569 continue;
571 gcov_write_unsigned (gfi_ptr->ident);
572 gcov_write_unsigned (gfi_ptr->lineno_checksum);
573 gcov_write_unsigned (gfi_ptr->cfg_checksum);
575 ci_ptr = gfi_ptr->ctrs;
576 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
578 gcov_unsigned_t n_counts;
579 gcov_type *c_ptr;
581 if (!gi_ptr->merge[t_ix])
582 continue;
584 n_counts = ci_ptr->num;
585 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
586 GCOV_TAG_COUNTER_LENGTH (n_counts));
587 c_ptr = ci_ptr->values;
588 while (n_counts--)
589 gcov_write_counter (*c_ptr++);
590 ci_ptr++;
592 if (buffered)
593 fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
596 gcov_write_unsigned (0);
599 /* Helper function for merging summary.
600 Return -1 on error. Return 0 on success. */
602 static int
603 merge_summary (const char *filename, int run_counted,
604 const struct gcov_info *gi_ptr, struct gcov_summary *prg,
605 struct gcov_summary *this_prg, gcov_unsigned_t crc32,
606 struct gcov_summary *all_prg __attribute__ ((unused)))
608 struct gcov_ctr_summary *cs_prg, *cs_tprg;
609 unsigned t_ix;
610 #if !GCOV_LOCKED
611 /* summary for all instances of program. */
612 struct gcov_ctr_summary *cs_all;
613 #endif
615 /* Merge the summaries. */
616 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
618 cs_prg = &(prg->ctrs[t_ix]);
619 cs_tprg = &(this_prg->ctrs[t_ix]);
621 if (gi_ptr->merge[t_ix])
623 int first = !cs_prg->runs;
625 if (!run_counted)
626 cs_prg->runs++;
627 if (first)
628 cs_prg->num = cs_tprg->num;
629 cs_prg->sum_all += cs_tprg->sum_all;
630 if (cs_prg->run_max < cs_tprg->run_max)
631 cs_prg->run_max = cs_tprg->run_max;
632 cs_prg->sum_max += cs_tprg->run_max;
633 if (first)
634 memcpy (cs_prg->histogram, cs_tprg->histogram,
635 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
636 else
637 gcov_histogram_merge (cs_prg->histogram, cs_tprg->histogram);
639 else if (cs_prg->runs)
641 gcov_error ("profiling:%s:Merge mismatch for summary.\n",
642 filename);
643 return -1;
645 #if !GCOV_LOCKED
646 cs_all = &all_prg->ctrs[t_ix];
647 if (!cs_all->runs && cs_prg->runs)
649 cs_all->num = cs_prg->num;
650 cs_all->runs = cs_prg->runs;
651 cs_all->sum_all = cs_prg->sum_all;
652 cs_all->run_max = cs_prg->run_max;
653 cs_all->sum_max = cs_prg->sum_max;
655 else if (!all_prg->checksum
656 /* Don't compare the histograms, which may have slight
657 variations depending on the order they were updated
658 due to the truncating integer divides used in the
659 merge. */
660 && (cs_all->num != cs_prg->num
661 || cs_all->runs != cs_prg->runs
662 || cs_all->sum_all != cs_prg->sum_all
663 || cs_all->run_max != cs_prg->run_max
664 || cs_all->sum_max != cs_prg->sum_max))
666 gcov_error ("profiling:%s:Data file mismatch - some "
667 "data files may have been concurrently "
668 "updated without locking support\n", filename);
669 all_prg->checksum = ~0u;
671 #endif
674 prg->checksum = crc32;
676 return 0;
680 /* Sort N entries in VALUE_ARRAY in descending order.
681 Each entry in VALUE_ARRAY has two values. The sorting
682 is based on the second value. */
684 GCOV_LINKAGE void
685 gcov_sort_n_vals (gcov_type *value_array, int n)
687 int j, k;
689 for (j = 2; j < n; j += 2)
691 gcov_type cur_ent[2];
693 cur_ent[0] = value_array[j];
694 cur_ent[1] = value_array[j + 1];
695 k = j - 2;
696 while (k >= 0 && value_array[k + 1] < cur_ent[1])
698 value_array[k + 2] = value_array[k];
699 value_array[k + 3] = value_array[k+1];
700 k -= 2;
702 value_array[k + 2] = cur_ent[0];
703 value_array[k + 3] = cur_ent[1];
707 /* Sort the profile counters for all indirect call sites. Counters
708 for each call site are allocated in array COUNTERS. */
710 static void
711 gcov_sort_icall_topn_counter (const struct gcov_ctr_info *counters)
713 int i;
714 gcov_type *values;
715 int n = counters->num;
717 gcc_assert (!(n % GCOV_ICALL_TOPN_NCOUNTS));
718 values = counters->values;
720 for (i = 0; i < n; i += GCOV_ICALL_TOPN_NCOUNTS)
722 gcov_type *value_array = &values[i + 1];
723 gcov_sort_n_vals (value_array, GCOV_ICALL_TOPN_NCOUNTS - 1);
727 /* Sort topn indirect_call profile counters in GI_PTR. */
729 static void
730 gcov_sort_topn_counter_arrays (const struct gcov_info *gi_ptr)
732 unsigned int i;
733 int f_ix;
734 const struct gcov_fn_info *gfi_ptr;
735 const struct gcov_ctr_info *ci_ptr;
737 if (!gi_ptr->merge[GCOV_COUNTER_ICALL_TOPNV])
738 return;
740 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
742 gfi_ptr = gi_ptr->functions[f_ix];
743 ci_ptr = gfi_ptr->ctrs;
744 for (i = 0; i < GCOV_COUNTERS; i++)
746 if (!gi_ptr->merge[i])
747 continue;
748 if (i == GCOV_COUNTER_ICALL_TOPNV)
750 gcov_sort_icall_topn_counter (ci_ptr);
751 break;
753 ci_ptr++;
758 /* Dump the coverage counts for one gcov_info object. We merge with existing
759 counts when possible, to avoid growing the .da files ad infinitum. We use
760 this program's checksum to make sure we only accumulate whole program
761 statistics to the correct summary. An object file might be embedded
762 in two separate programs, and we must keep the two program
763 summaries separate. */
765 static void
766 dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
767 unsigned run_counted,
768 gcov_unsigned_t crc32, struct gcov_summary *all_prg,
769 struct gcov_summary *this_prg)
771 struct gcov_summary prg; /* summary for this object over all program. */
772 int error;
773 gcov_unsigned_t tag;
774 gcov_position_t summary_pos = 0;
775 gcov_position_t eof_pos = 0;
777 fn_buffer = 0;
778 sum_buffer = 0;
780 gcov_sort_topn_counter_arrays (gi_ptr);
782 error = gcov_exit_open_gcda_file (gi_ptr, gf);
783 if (error == -1)
784 return;
786 tag = gcov_read_unsigned ();
787 if (tag)
789 /* Merge data from file. */
790 if (tag != GCOV_DATA_MAGIC)
792 gcov_error ("profiling:%s:Not a gcov data file\n", gf->filename);
793 goto read_fatal;
795 error = merge_one_data (gf->filename, gi_ptr, &prg, this_prg,
796 &summary_pos, &eof_pos, crc32);
797 if (error == -1)
798 goto read_fatal;
801 gcov_rewrite ();
803 if (!summary_pos)
805 memset (&prg, 0, sizeof (prg));
806 summary_pos = eof_pos;
809 error = merge_summary (gf->filename, run_counted, gi_ptr, &prg, this_prg,
810 crc32, all_prg);
811 if (error == -1)
812 goto read_fatal;
814 write_one_data (gi_ptr, &prg, eof_pos, summary_pos);
815 /* fall through */
817 read_fatal:;
818 while (fn_buffer)
819 fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
821 if ((error = gcov_close ()))
822 gcov_error (error < 0 ?
823 "profiling:%s:Overflow writing\n" :
824 "profiling:%s:Error writing\n",
825 gf->filename);
829 /* Dump all the coverage counts for the program. It first computes program
830 summary and then traverses gcov_list list and dumps the gcov_info
831 objects one by one. */
833 #if !IN_GCOV_TOOL
834 static
835 #endif
836 void
837 gcov_do_dump (struct gcov_info *list, int run_counted)
839 struct gcov_info *gi_ptr;
840 struct gcov_filename gf;
841 gcov_unsigned_t crc32;
842 struct gcov_summary all_prg;
843 struct gcov_summary this_prg;
845 crc32 = compute_summary (list, &this_prg, &gf.max_length);
847 allocate_filename_struct (&gf);
848 #if !GCOV_LOCKED
849 memset (&all_prg, 0, sizeof (all_prg));
850 #endif
852 /* Now merge each file. */
853 for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
854 dump_one_gcov (gi_ptr, &gf, run_counted, crc32, &all_prg, &this_prg);
856 free (gf.filename);
859 #if IN_GCOV_TOOL
860 const char *
861 __attribute__ ((unused))
862 gcov_get_filename (struct gcov_info *list)
864 return list->filename;
866 #endif
868 #if !IN_GCOV_TOOL
869 void
870 __gcov_dump_one (struct gcov_root *root)
872 if (root->dumped)
873 return;
875 gcov_do_dump (root->list, root->run_counted);
877 root->dumped = 1;
878 root->run_counted = 1;
881 /* Per-dynamic-object gcov state. */
882 struct gcov_root __gcov_root;
884 /* Exactly one of these will be live in the process image. */
885 struct gcov_master __gcov_master =
886 {GCOV_VERSION, 0};
888 void
889 __gcov_exit (void)
891 __gcov_dump_one (&__gcov_root);
892 if (__gcov_root.next)
893 __gcov_root.next->prev = __gcov_root.prev;
894 if (__gcov_root.prev)
895 __gcov_root.prev->next = __gcov_root.next;
896 else
897 __gcov_master.root = __gcov_root.next;
899 gcov_error_exit ();
902 /* Add a new object file onto the bb chain. Invoked automatically
903 when running an object file's global ctors. */
905 void
906 __gcov_init (struct gcov_info *info)
908 if (!info->version || !info->n_functions)
909 return;
910 if (gcov_version (info, info->version, 0))
912 if (!__gcov_root.list)
914 /* Add to master list and at exit function. */
915 if (gcov_version (NULL, __gcov_master.version, "<master>"))
917 __gcov_root.next = __gcov_master.root;
918 if (__gcov_master.root)
919 __gcov_master.root->prev = &__gcov_root;
920 __gcov_master.root = &__gcov_root;
924 info->next = __gcov_root.list;
925 __gcov_root.list = info;
928 #endif /* !IN_GCOV_TOOL */
929 #endif /* L_gcov */
930 #endif /* inhibit_libc */