1/* Routines required for instrumenting a program. */ 2/* Compile this one with gcc. */ 3/* Copyright (C) 1989-2014 Free Software Foundation, Inc. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free 9Software Foundation; either version 3, or (at your option) any later 10version. 11 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17Under Section 7 of GPL version 3, you are granted additional 18permissions described in the GCC Runtime Library Exception, version 193.1, as published by the Free Software Foundation. 20 21You should have received a copy of the GNU General Public License and 22a copy of the GCC Runtime Library Exception along with this program; 23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24<http://www.gnu.org/licenses/>. */ 25 26#include "libgcov.h" 27 28#if defined(inhibit_libc) 29/* If libc and its header files are not available, provide dummy functions. */ 30 31#if defined(L_gcov) 32void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {} 33#endif 34 35#else /* inhibit_libc */ 36 37#include <string.h> 38#if GCOV_LOCKED 39#include <fcntl.h> 40#include <errno.h> 41#include <sys/stat.h> 42#endif 43 44#ifdef L_gcov 45#include "gcov-io.c" 46 47#ifndef IN_GCOV_TOOL 48extern gcov_unsigned_t __gcov_sampling_period; 49extern gcov_unsigned_t __gcov_has_sampling; 50static int gcov_sampling_period_initialized = 0; 51#endif 52 53/* Unique identifier assigned to each module (object file). */ 54static gcov_unsigned_t gcov_cur_module_id = 0; 55 56 57/* Dynamic call graph build and form module groups. */ 58int __gcov_compute_module_groups (void) ATTRIBUTE_HIDDEN; 59void __gcov_finalize_dyn_callgraph (void) ATTRIBUTE_HIDDEN; 60 61/* The following functions can be called from outside of this file. */ 62extern void gcov_clear (void) ATTRIBUTE_HIDDEN; 63extern void gcov_exit (void) ATTRIBUTE_HIDDEN; 64extern void set_gcov_dump_complete (void) ATTRIBUTE_HIDDEN; 65extern void reset_gcov_dump_complete (void) ATTRIBUTE_HIDDEN; 66extern int get_gcov_dump_complete (void) ATTRIBUTE_HIDDEN; 67extern void set_gcov_list (struct gcov_info *) ATTRIBUTE_HIDDEN; 68__attribute__((weak)) void __coverage_callback (gcov_type, int); 69 70#ifndef IN_GCOV_TOOL 71/* Create a strong reference to these symbols so that they are 72 unconditionally pulled into the instrumented binary, even when 73 the only reference is a weak reference. This is necessary because 74 we are using weak references to enable references from code that 75 may not be linked with libgcov. These are the only symbols that 76 should be accessed via link references from application code! 77 78 A subtlety of the linker is that it will only resolve weak references 79 defined within archive libraries when there is a strong reference to 80 something else defined within the same object file. Since these functions 81 are defined within their own object files, they would not automatically 82 get resolved. Since there are symbols within the main L_gcov 83 section that are strongly referenced during -fprofile-generate and 84 -ftest-coverage builds, these dummy symbols will always need to be 85 resolved. */ 86void (*__gcov_dummy_ref1)(void) = &__gcov_reset; 87void (*__gcov_dummy_ref2)(void) = &__gcov_dump; 88extern char *__gcov_get_profile_prefix (void); 89char *(*__gcov_dummy_ref3)(void) = &__gcov_get_profile_prefix; 90extern void __gcov_set_sampling_period (unsigned int period); 91char *(*__gcov_dummy_ref4)(void) = &__gcov_set_sampling_period; 92extern unsigned int __gcov_sampling_enabled (void); 93char *(*__gcov_dummy_ref5)(void) = &__gcov_sampling_enabled; 94extern void __gcov_flush (void); 95char *(*__gcov_dummy_ref6)(void) = &__gcov_flush; 96extern unsigned int __gcov_profiling_for_test_coverage (void); 97char *(*__gcov_dummy_ref7)(void) = &__gcov_profiling_for_test_coverage; 98#endif 99 100/* Default callback function for profile instrumentation callback. */ 101__attribute__((weak)) void 102__coverage_callback (gcov_type funcdef_no __attribute__ ((unused)), 103 int edge_no __attribute__ ((unused))) 104{ 105 /* nothing */ 106} 107 108struct gcov_fn_buffer 109{ 110 struct gcov_fn_buffer *next; 111 unsigned fn_ix; 112 struct gcov_fn_info info; 113 /* note gcov_fn_info ends in a trailing array. */ 114}; 115 116struct gcov_summary_buffer 117{ 118 struct gcov_summary_buffer *next; 119 struct gcov_summary summary; 120}; 121 122/* Chain of per-object gcov structures. */ 123extern struct gcov_info *__gcov_list; 124 125/* Set the head of gcov_list. */ 126void 127set_gcov_list (struct gcov_info *head) 128{ 129 __gcov_list = head; 130} 131 132/* Size of the longest file name. */ 133/* We need to expose this static variable when compiling for gcov-tool. */ 134#ifndef IN_GCOV_TOOL 135static 136#endif 137size_t gcov_max_filename = 0; 138 139/* Flag when the profile has already been dumped via __gcov_dump(). */ 140static int gcov_dump_complete; 141 142/* A global function that get the vaule of gcov_dump_complete. */ 143 144int 145get_gcov_dump_complete (void) 146{ 147 return gcov_dump_complete; 148} 149 150/* A global functino that set the vaule of gcov_dump_complete. Will 151 be used in __gcov_dump() in libgcov-interface.c. */ 152 153void 154set_gcov_dump_complete (void) 155{ 156 gcov_dump_complete = 1; 157} 158 159/* A global functino that set the vaule of gcov_dump_complete. Will 160 be used in __gcov_reset() in libgcov-interface.c. */ 161 162void 163reset_gcov_dump_complete (void) 164{ 165 gcov_dump_complete = 0; 166} 167 168/* A utility function for outputing errors. */ 169static int gcov_error (const char *, ...); 170 171static struct gcov_fn_buffer * 172free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer, 173 unsigned limit) 174{ 175 struct gcov_fn_buffer *next; 176 unsigned ix, n_ctr = 0; 177 178 if (!buffer) 179 return 0; 180 next = buffer->next; 181 182 for (ix = 0; ix != limit; ix++) 183 if (gi_ptr->merge[ix]) 184 free (buffer->info.ctrs[n_ctr++].values); 185 free (buffer); 186 return next; 187} 188 189static struct gcov_fn_buffer ** 190buffer_fn_data (const char *filename, const struct gcov_info *gi_ptr, 191 struct gcov_fn_buffer **end_ptr, unsigned fn_ix) 192{ 193 unsigned n_ctrs = 0, ix = 0; 194 struct gcov_fn_buffer *fn_buffer; 195 unsigned len; 196 197 for (ix = GCOV_COUNTERS; ix--;) 198 if (gi_ptr->merge[ix]) 199 n_ctrs++; 200 201 len = sizeof (*fn_buffer) + sizeof (fn_buffer->info.ctrs[0]) * n_ctrs; 202 fn_buffer = (struct gcov_fn_buffer *) xmalloc (len); 203 204 if (!fn_buffer) 205 goto fail; 206 207 fn_buffer->next = 0; 208 fn_buffer->fn_ix = fn_ix; 209 fn_buffer->info.ident = gcov_read_unsigned (); 210 fn_buffer->info.lineno_checksum = gcov_read_unsigned (); 211 fn_buffer->info.cfg_checksum = gcov_read_unsigned (); 212 213 for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++) 214 { 215 gcov_unsigned_t length; 216 gcov_type *values; 217 218 if (!gi_ptr->merge[ix]) 219 continue; 220 221 if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix)) 222 { 223 len = 0; 224 goto fail; 225 } 226 227 length = GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ()); 228 len = length * sizeof (gcov_type); 229 values = (gcov_type *) xmalloc (len); 230 if (!values) 231 goto fail; 232 233 fn_buffer->info.ctrs[n_ctrs].num = length; 234 fn_buffer->info.ctrs[n_ctrs].values = values; 235 236 while (length--) 237 *values++ = gcov_read_counter (); 238 n_ctrs++; 239 } 240 241 *end_ptr = fn_buffer; 242 return &fn_buffer->next; 243 244fail: 245 gcov_error ("profiling:%s:Function %u %s %u \n", filename, fn_ix, 246 len ? "cannot allocate" : "counter mismatch", len ? len : ix); 247 248 return (struct gcov_fn_buffer **)free_fn_data (gi_ptr, fn_buffer, ix); 249} 250 251/* Determine whether a counter is active. */ 252 253static inline int 254gcov_counter_active (const struct gcov_info *info, unsigned int type) 255{ 256 return (info->merge[type] != 0); 257} 258 259/* Add an unsigned value to the current crc */ 260 261static gcov_unsigned_t 262crc32_unsigned (gcov_unsigned_t crc32, gcov_unsigned_t value) 263{ 264 unsigned ix; 265 266 for (ix = 32; ix--; value <<= 1) 267 { 268 unsigned feedback; 269 270 feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0; 271 crc32 <<= 1; 272 crc32 ^= feedback; 273 } 274 275 return crc32; 276} 277 278/* Check if VERSION of the info block PTR matches libgcov one. 279 Return 1 on success, or zero in case of versions mismatch. 280 If FILENAME is not NULL, its value used for reporting purposes 281 instead of value from the info block. */ 282 283static int 284gcov_version (struct gcov_info *ptr, gcov_unsigned_t version, 285 const char *filename) 286{ 287 if (version != GCOV_VERSION) 288 { 289 char v[4], e[4]; 290 291 GCOV_UNSIGNED2STRING (v, version); 292 GCOV_UNSIGNED2STRING (e, GCOV_VERSION); 293 294 if (filename) 295 gcov_error ("profiling:%s:Version mismatch - expected %.4s got %.4s\n", 296 filename? filename : ptr->filename, e, v); 297 else 298 gcov_error ("profiling:Version mismatch - expected %.4s got %.4s\n", e, v); 299 300 return 0; 301 } 302 return 1; 303} 304 305/* Insert counter VALUE into HISTOGRAM. */ 306 307static void 308gcov_histogram_insert(gcov_bucket_type *histogram, gcov_type value) 309{ 310 unsigned i; 311 312 i = gcov_histo_index(value); 313 histogram[i].num_counters++; 314 histogram[i].cum_value += value; 315 if (value < histogram[i].min_value) 316 histogram[i].min_value = value; 317} 318 319/* Computes a histogram of the arc counters to place in the summary SUM. */ 320 321static void 322gcov_compute_histogram (struct gcov_summary *sum) 323{ 324 struct gcov_info *gi_ptr; 325 const struct gcov_fn_info *gfi_ptr; 326 const struct gcov_ctr_info *ci_ptr; 327 struct gcov_ctr_summary *cs_ptr; 328 unsigned t_ix, f_ix, ctr_info_ix, ix; 329 int h_ix; 330 331 /* This currently only applies to arc counters. */ 332 t_ix = GCOV_COUNTER_ARCS; 333 334 /* First check if there are any counts recorded for this counter. */ 335 cs_ptr = &(sum->ctrs[t_ix]); 336 if (!cs_ptr->num) 337 return; 338 339 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) 340 { 341 cs_ptr->histogram[h_ix].num_counters = 0; 342 cs_ptr->histogram[h_ix].min_value = cs_ptr->run_max; 343 cs_ptr->histogram[h_ix].cum_value = 0; 344 } 345 346 /* Walk through all the per-object structures and record each of 347 the count values in histogram. */ 348 for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next) 349 { 350 if (!gi_ptr->merge[t_ix]) 351 continue; 352 353 /* Find the appropriate index into the gcov_ctr_info array 354 for the counter we are currently working on based on the 355 existence of the merge function pointer for this object. */ 356 for (ix = 0, ctr_info_ix = 0; ix < t_ix; ix++) 357 { 358 if (gi_ptr->merge[ix]) 359 ctr_info_ix++; 360 } 361 for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++) 362 { 363 gfi_ptr = gi_ptr->functions[f_ix]; 364 365 if (!gfi_ptr || gfi_ptr->key != gi_ptr) 366 continue; 367 368 ci_ptr = &gfi_ptr->ctrs[ctr_info_ix]; 369 for (ix = 0; ix < ci_ptr->num; ix++) 370 gcov_histogram_insert (cs_ptr->histogram, ci_ptr->values[ix]); 371 } 372 } 373} 374 375/* gcda filename. */ 376static char *gi_filename; 377/* buffer for the fn_data from another program. */ 378static struct gcov_fn_buffer *fn_buffer; 379/* buffer for summary from other programs to be written out. */ 380static struct gcov_summary_buffer *sum_buffer; 381/* If application calls fork or exec multiple times, we end up storing 382 profile repeadely. We should not account this as multiple runs or 383 functions executed once may mistakely become cold. */ 384static int run_accounted = 0; 385 386/* This funtions computes the program level summary and the histo-gram. 387 It computes and returns CRC32 and stored summary in THIS_PRG. */ 388 389static gcov_unsigned_t 390gcov_exit_compute_summary (struct gcov_summary *this_prg) 391{ 392 struct gcov_info *gi_ptr; 393 const struct gcov_fn_info *gfi_ptr; 394 struct gcov_ctr_summary *cs_ptr; 395 const struct gcov_ctr_info *ci_ptr; 396 int f_ix; 397 unsigned t_ix; 398 gcov_unsigned_t c_num; 399 gcov_unsigned_t crc32 = 0; 400 401 /* Find the totals for this execution. */ 402 memset (this_prg, 0, sizeof (*this_prg)); 403 for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next) 404 { 405 crc32 = crc32_unsigned (crc32, gi_ptr->stamp); 406 crc32 = crc32_unsigned (crc32, gi_ptr->n_functions); 407 408 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++) 409 { 410 gfi_ptr = gi_ptr->functions[f_ix]; 411 412 if (gfi_ptr && gfi_ptr->key != gi_ptr) 413 gfi_ptr = 0; 414 415 crc32 = crc32_unsigned (crc32, gfi_ptr ? gfi_ptr->cfg_checksum : 0); 416 crc32 = crc32_unsigned (crc32, 417 gfi_ptr ? gfi_ptr->lineno_checksum : 0); 418 if (!gfi_ptr) 419 continue; 420 421 ci_ptr = gfi_ptr->ctrs; 422 for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++) 423 { 424 if (!gi_ptr->merge[t_ix]) 425 continue; 426 427 cs_ptr = &(this_prg->ctrs[t_ix]); 428 cs_ptr->num += ci_ptr->num; 429 crc32 = crc32_unsigned (crc32, ci_ptr->num); 430 431 for (c_num = 0; c_num < ci_ptr->num; c_num++) 432 { 433 cs_ptr->sum_all += ci_ptr->values[c_num]; 434 if (cs_ptr->run_max < ci_ptr->values[c_num]) 435 cs_ptr->run_max = ci_ptr->values[c_num]; 436 } 437 ci_ptr++; 438 } 439 } 440 } 441 gcov_compute_histogram (this_prg); 442 return crc32; 443} 444 445/* A struct that bundles all the related information about the 446 gcda filename. */ 447struct gcov_filename_aux{ 448 char *gi_filename_up; 449 int gcov_prefix_strip; 450 size_t prefix_length; 451}; 452 453/* Including system dependent components. */ 454#include "libgcov-driver-system.c" 455 456/* Scan through the current open gcda file corresponding to GI_PTR 457 to locate the end position of the last summary, returned in 458 SUMMARY_END_POS_P. Return 0 on success, -1 on error. */ 459static int 460gcov_scan_summary_end (struct gcov_info *gi_ptr, 461 gcov_position_t *summary_end_pos_p) 462{ 463 gcov_unsigned_t tag, version, stamp; 464 tag = gcov_read_unsigned (); 465 if (tag != GCOV_DATA_MAGIC) 466 { 467 gcov_error ("profiling:%s:Not a gcov data file\n", gi_filename); 468 return -1; 469 } 470 471 version = gcov_read_unsigned (); 472 if (!gcov_version (gi_ptr, version, gi_filename)) 473 return -1; 474 475 stamp = gcov_read_unsigned (); 476 if (stamp != gi_ptr->stamp) 477 /* Read from a different compilation. Overwrite the file. */ 478 return -1; 479 480 /* Look for program summary. */ 481 while (1) 482 { 483 struct gcov_summary tmp; 484 485 *summary_end_pos_p = gcov_position (); 486 tag = gcov_read_unsigned (); 487 if (tag != GCOV_TAG_PROGRAM_SUMMARY) 488 break; 489 490 gcov_read_unsigned (); 491 gcov_read_summary (&tmp); 492 if (gcov_is_error ()) 493 return -1; 494 } 495 496 return 0; 497} 498 499/* This function merges counters in GI_PTR to an existing gcda file. 500 Return 0 on success. 501 Return -1 on error. In this case, caller will goto read_fatal. */ 502 503static int 504gcov_exit_merge_gcda (struct gcov_info *gi_ptr, 505 struct gcov_summary *prg_p, 506 struct gcov_summary *this_prg, 507 gcov_position_t *summary_pos_p, 508 gcov_position_t *eof_pos_p, 509 gcov_unsigned_t crc32) 510{ 511 gcov_unsigned_t tag, length; 512 unsigned t_ix; 513 int f_ix; 514 int error = 0; 515 struct gcov_fn_buffer **fn_tail = &fn_buffer; 516 struct gcov_summary_buffer **sum_tail = &sum_buffer; 517 518 length = gcov_read_unsigned (); 519 if (!gcov_version (gi_ptr, length, gi_filename)) 520 return -1; 521 522 length = gcov_read_unsigned (); 523 if (length != gi_ptr->stamp) 524 /* Read from a different compilation. Overwrite the file. */ 525 return 0; 526 527 /* Look for program summary. */ 528 for (f_ix = 0;;) 529 { 530 struct gcov_summary tmp; 531 532 *eof_pos_p = gcov_position (); 533 tag = gcov_read_unsigned (); 534 if (tag != GCOV_TAG_PROGRAM_SUMMARY) 535 break; 536 537 f_ix--; 538 length = gcov_read_unsigned (); 539 gcov_read_summary (&tmp); 540 if ((error = gcov_is_error ())) 541 goto read_error; 542 if (*summary_pos_p) 543 { 544 /* Save all summaries after the one that will be 545 merged into below. These will need to be rewritten 546 as histogram merging may change the number of non-zero 547 histogram entries that will be emitted, and thus the 548 size of the merged summary. */ 549 (*sum_tail) = (struct gcov_summary_buffer *) 550 xmalloc (sizeof(struct gcov_summary_buffer)); 551 (*sum_tail)->summary = tmp; 552 (*sum_tail)->next = 0; 553 sum_tail = &((*sum_tail)->next); 554 goto next_summary; 555 } 556 if (tmp.checksum != crc32) 557 goto next_summary; 558 559 for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++) 560 if (tmp.ctrs[t_ix].num != this_prg->ctrs[t_ix].num) 561 goto next_summary; 562 *prg_p = tmp; 563 *summary_pos_p = *eof_pos_p; 564 565 next_summary:; 566 } 567 568 /* Merge execution counts for each function. */ 569 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; 570 f_ix++, tag = gcov_read_unsigned ()) 571 { 572 const struct gcov_ctr_info *ci_ptr; 573 const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix]; 574 575 if (tag != GCOV_TAG_FUNCTION) 576 goto read_mismatch; 577 578 length = gcov_read_unsigned (); 579 if (!length) 580 /* This function did not appear in the other program. 581 We have nothing to merge. */ 582 continue; 583 584 if (length != GCOV_TAG_FUNCTION_LENGTH) 585 goto read_mismatch; 586 587 if (!gfi_ptr || gfi_ptr->key != gi_ptr) 588 { 589 /* This function appears in the other program. We 590 need to buffer the information in order to write 591 it back out -- we'll be inserting data before 592 this point, so cannot simply keep the data in the 593 file. */ 594 fn_tail = buffer_fn_data (gi_filename, 595 gi_ptr, fn_tail, f_ix); 596 if (!fn_tail) 597 goto read_mismatch; 598 continue; 599 } 600 601 length = gcov_read_unsigned (); 602 if (length != gfi_ptr->ident) 603 goto read_mismatch; 604 605 length = gcov_read_unsigned (); 606 if (length != gfi_ptr->lineno_checksum) 607 goto read_mismatch; 608 609 length = gcov_read_unsigned (); 610 if (length != gfi_ptr->cfg_checksum) 611 goto read_mismatch; 612 613 ci_ptr = gfi_ptr->ctrs; 614 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++) 615 { 616 gcov_merge_fn merge = gi_ptr->merge[t_ix]; 617 618 if (!merge) 619 continue; 620 621 tag = gcov_read_unsigned (); 622 length = gcov_read_unsigned (); 623 if (tag != GCOV_TAG_FOR_COUNTER (t_ix) 624 || length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num)) 625 goto read_mismatch; 626 (*merge) (ci_ptr->values, ci_ptr->num); 627 ci_ptr++; 628 } 629 if ((error = gcov_is_error ())) 630 goto read_error; 631 } 632 633 if (tag && tag != GCOV_TAG_MODULE_INFO) 634 { 635 read_mismatch:; 636 gcov_error ("profiling:%s:Merge mismatch for %s %u\n", 637 gi_filename, f_ix >= 0 ? "function" : "summary", 638 f_ix < 0 ? -1 - f_ix : f_ix); 639 return -1; 640 } 641 return 0; 642 643read_error: 644 gcov_error ("profiling:%s:%s merging\n", gi_filename, 645 error < 0 ? "Overflow": "Error"); 646 return -1; 647} 648 649/* Write counters in GI_PTR to a gcda file starting from its current 650 location. */ 651 652static void 653gcov_write_func_counters (struct gcov_info *gi_ptr) 654{ 655 unsigned f_ix; 656 657 /* Write execution counts for each function. */ 658 for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++) 659 { 660 unsigned buffered = 0; 661 const struct gcov_fn_info *gfi_ptr; 662 const struct gcov_ctr_info *ci_ptr; 663 gcov_unsigned_t length; 664 unsigned t_ix; 665 666 if (fn_buffer && fn_buffer->fn_ix == f_ix) 667 { 668 /* Buffered data from another program. */ 669 buffered = 1; 670 gfi_ptr = &fn_buffer->info; 671 length = GCOV_TAG_FUNCTION_LENGTH; 672 } 673 else 674 { 675 gfi_ptr = gi_ptr->functions[f_ix]; 676 if (gfi_ptr && gfi_ptr->key == gi_ptr) 677 length = GCOV_TAG_FUNCTION_LENGTH; 678 else 679 length = 0; 680 } 681 682 gcov_write_tag_length (GCOV_TAG_FUNCTION, length); 683 if (!length) 684 continue; 685 686 gcov_write_unsigned (gfi_ptr->ident); 687 gcov_write_unsigned (gfi_ptr->lineno_checksum); 688 gcov_write_unsigned (gfi_ptr->cfg_checksum); 689 690 ci_ptr = gfi_ptr->ctrs; 691 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++) 692 { 693 gcov_unsigned_t n_counts; 694 gcov_type *c_ptr; 695 696 if (!gi_ptr->merge[t_ix]) 697 continue; 698 699 n_counts = ci_ptr->num; 700 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix), 701 GCOV_TAG_COUNTER_LENGTH (n_counts)); 702 c_ptr = ci_ptr->values; 703 while (n_counts--) 704 gcov_write_counter (*c_ptr++); 705 ci_ptr++; 706 } 707 if (buffered) 708 fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS); 709 } 710 711 gi_ptr->eof_pos = gcov_position (); 712 gcov_write_unsigned (0); 713} 714 715/* Write counters in GI_PTR and the summary in PRG to a gcda file. In 716 the case of appending to an existing file, SUMMARY_POS will be non-zero. 717 We will write the file starting from SUMMAY_POS. */ 718 719static void 720gcov_exit_write_gcda (struct gcov_info *gi_ptr, 721 const struct gcov_summary *prg_p, 722 const gcov_position_t eof_pos, 723 const gcov_position_t summary_pos) 724 725{ 726 struct gcov_summary_buffer *next_sum_buffer; 727 728 /* Write out the data. */ 729 if (!eof_pos) 730 { 731 gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION); 732 gcov_write_unsigned (gi_ptr->stamp); 733 } 734 735 if (summary_pos) 736 gcov_seek (summary_pos); 737 gcc_assert (!summary_pos || summary_pos == gcov_position ()); 738 739 /* Generate whole program statistics. */ 740 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, prg_p); 741 742 /* Rewrite all the summaries that were after the summary we merged 743 into. This is necessary as the merged summary may have a different 744 size due to the number of non-zero histogram entries changing after 745 merging. */ 746 747 while (sum_buffer) 748 { 749 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &sum_buffer->summary); 750 next_sum_buffer = sum_buffer->next; 751 free (sum_buffer); 752 sum_buffer = next_sum_buffer; 753 } 754 755 /* Write the counters. */ 756 gcov_write_func_counters (gi_ptr); 757} 758 759/* Helper function for merging summary. 760 Return -1 on error. Return 0 on success. */ 761 762static int 763gcov_exit_merge_summary (const struct gcov_info *gi_ptr, struct gcov_summary *prg, 764 struct gcov_summary *this_prg, gcov_unsigned_t crc32, 765 struct gcov_summary *all_prg __attribute__ ((unused))) 766{ 767 struct gcov_ctr_summary *cs_prg, *cs_tprg; 768 unsigned t_ix; 769#if !GCOV_LOCKED 770 /* summary for all instances of program. */ 771 struct gcov_ctr_summary *cs_all; 772#endif 773 774 /* Merge the summaries. */ 775 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++) 776 { 777 cs_prg = &(prg->ctrs[t_ix]); 778 cs_tprg = &(this_prg->ctrs[t_ix]); 779 780 if (gi_ptr->merge[t_ix]) 781 { 782 int first = !cs_prg->runs; 783 784 if (!run_accounted) 785 cs_prg->runs++; 786 if (first) 787 cs_prg->num = cs_tprg->num; 788 cs_prg->sum_all += cs_tprg->sum_all; 789 if (cs_prg->run_max < cs_tprg->run_max) 790 cs_prg->run_max = cs_tprg->run_max; 791 cs_prg->sum_max += cs_tprg->run_max; 792 if (first) 793 memcpy (cs_prg->histogram, cs_tprg->histogram, 794 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); 795 else 796 gcov_histogram_merge (cs_prg->histogram, cs_tprg->histogram); 797 } 798 else if (cs_prg->runs) 799 { 800 gcov_error ("profiling:%s:Merge mismatch for summary.\n", 801 gi_filename); 802 return -1; 803 } 804#if !GCOV_LOCKED 805 cs_all = &all_prg->ctrs[t_ix]; 806 if (!cs_all->runs && cs_prg->runs) 807 { 808 cs_all->num = cs_prg->num; 809 cs_all->runs = cs_prg->runs; 810 cs_all->sum_all = cs_prg->sum_all; 811 cs_all->run_max = cs_prg->run_max; 812 cs_all->sum_max = cs_prg->sum_max; 813 } 814 else if (!all_prg->checksum 815 /* Don't compare the histograms, which may have slight 816 variations depending on the order they were updated 817 due to the truncating integer divides used in the 818 merge. */ 819 && (cs_all->num != cs_prg->num 820 || cs_all->runs != cs_prg->runs 821 || cs_all->sum_all != cs_prg->sum_all 822 || cs_all->run_max != cs_prg->run_max 823 || cs_all->sum_max != cs_prg->sum_max)) 824 { 825 gcov_error ("profiling:%s:Data file mismatch - some " 826 "data files may have been concurrently " 827 "updated without locking support\n", gi_filename); 828 all_prg->checksum = ~0u; 829 } 830#endif 831 } 832 833 prg->checksum = crc32; 834 835 return 0; 836} 837 838/* Sort N entries in VALUE_ARRAY in descending order. 839 Each entry in VALUE_ARRAY has two values. The sorting 840 is based on the second value. */ 841 842GCOV_LINKAGE void 843gcov_sort_n_vals (gcov_type *value_array, int n) 844{ 845 int j, k; 846 for (j = 2; j < n; j += 2) 847 { 848 gcov_type cur_ent[2]; 849 cur_ent[0] = value_array[j]; 850 cur_ent[1] = value_array[j + 1]; 851 k = j - 2; 852 while (k >= 0 && value_array[k + 1] < cur_ent[1]) 853 { 854 value_array[k + 2] = value_array[k]; 855 value_array[k + 3] = value_array[k+1]; 856 k -= 2; 857 } 858 value_array[k + 2] = cur_ent[0]; 859 value_array[k + 3] = cur_ent[1]; 860 } 861} 862 863/* Sort the profile counters for all indirect call sites. Counters 864 for each call site are allocated in array COUNTERS. */ 865 866static void 867gcov_sort_icall_topn_counter (const struct gcov_ctr_info *counters) 868{ 869 int i; 870 gcov_type *values; 871 int n = counters->num; 872 gcc_assert (!(n % GCOV_ICALL_TOPN_NCOUNTS)); 873 874 values = counters->values; 875 876 for (i = 0; i < n; i += GCOV_ICALL_TOPN_NCOUNTS) 877 { 878 gcov_type *value_array = &values[i + 1]; 879 gcov_sort_n_vals (value_array, GCOV_ICALL_TOPN_NCOUNTS - 1); 880 } 881} 882 883static void 884gcov_sort_topn_counter_arrays (const struct gcov_info *gi_ptr) 885{ 886 unsigned int i; 887 int f_ix; 888 const struct gcov_fn_info *gfi_ptr; 889 const struct gcov_ctr_info *ci_ptr; 890 891 for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++) 892 { 893 gfi_ptr = gi_ptr->functions[f_ix]; 894 ci_ptr = gfi_ptr->ctrs; 895 for (i = 0; i < GCOV_COUNTERS; i++) 896 { 897 if (!gcov_counter_active (gi_ptr, i)) 898 continue; 899 if (i == GCOV_COUNTER_ICALL_TOPNV) 900 { 901 gcov_sort_icall_topn_counter (ci_ptr); 902 break; 903 } 904 ci_ptr++; 905 } 906 } 907} 908 909/* Dump the coverage counts for one gcov_info object. We merge with existing 910 counts when possible, to avoid growing the .da files ad infinitum. We use 911 this program's checksum to make sure we only accumulate whole program 912 statistics to the correct summary. An object file might be embedded 913 in two separate programs, and we must keep the two program 914 summaries separate. */ 915 916static void 917gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf, 918 gcov_unsigned_t crc32, struct gcov_summary *all_prg, 919 struct gcov_summary *this_prg) 920{ 921 struct gcov_summary prg; /* summary for this object over all program. */ 922 int error; 923 gcov_unsigned_t tag; 924 gcov_position_t summary_pos = 0; 925 gcov_position_t eof_pos = 0; 926 927 fn_buffer = 0; 928 sum_buffer = 0; 929 930 gcov_sort_topn_counter_arrays (gi_ptr); 931 932 error = gcov_exit_open_gcda_file (gi_ptr, gf); 933 if (error == -1) 934 return; 935 936 tag = gcov_read_unsigned (); 937 if (tag) 938 { 939 /* Merge data from file. */ 940 if (tag != GCOV_DATA_MAGIC) 941 { 942 gcov_error ("profiling:%s:Not a gcov data file\n", gi_filename); 943 goto read_fatal; 944 } 945 error = gcov_exit_merge_gcda (gi_ptr, &prg, this_prg, &summary_pos, &eof_pos, 946 crc32); 947 if (error == -1) 948 goto read_fatal; 949 } 950 951 gcov_rewrite (); 952 953 if (!summary_pos) 954 { 955 memset (&prg, 0, sizeof (prg)); 956 summary_pos = eof_pos; 957 } 958 959 error = gcov_exit_merge_summary (gi_ptr, &prg, this_prg, crc32, all_prg); 960 if (error == -1) 961 goto read_fatal; 962 963 gcov_exit_write_gcda (gi_ptr, &prg, eof_pos, summary_pos); 964 /* fall through */ 965 966read_fatal:; 967 while (fn_buffer) 968 fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS); 969 970 if ((error = gcov_close ())) 971 gcov_error (error < 0 ? 972 "profiling:%s:Overflow writing\n" : 973 "profiling:%s:Error writing\n", 974 gi_filename); 975} 976 977/* Write imported files (auxiliary modules) for primary module GI_PTR 978 into file GI_FILENAME. */ 979 980static void 981gcov_write_import_file (char *gi_filename, struct gcov_info *gi_ptr) 982{ 983 char *gi_imports_filename; 984 const char *gcov_suffix; 985 FILE *imports_file; 986 size_t prefix_length, suffix_length; 987 988 gcov_suffix = getenv ("GCOV_IMPORTS_SUFFIX"); 989 if (!gcov_suffix || !strlen (gcov_suffix)) 990 gcov_suffix = ".imports"; 991 suffix_length = strlen (gcov_suffix); 992 prefix_length = strlen (gi_filename); 993 gi_imports_filename = (char *) alloca (prefix_length + suffix_length + 1); 994 memset (gi_imports_filename, 0, prefix_length + suffix_length + 1); 995 memcpy (gi_imports_filename, gi_filename, prefix_length); 996 memcpy (gi_imports_filename + prefix_length, gcov_suffix, suffix_length); 997 imports_file = fopen (gi_imports_filename, "w"); 998 if (imports_file) 999 { 1000 const struct dyn_imp_mod **imp_mods; 1001 unsigned i, imp_len; 1002 imp_mods = gcov_get_sorted_import_module_array (gi_ptr, &imp_len); 1003 if (imp_mods) 1004 { 1005 for (i = 0; i < imp_len; i++) 1006 { 1007 fprintf (imports_file, "%s\n", 1008 imp_mods[i]->imp_mod->mod_info->source_filename); 1009 fprintf (imports_file, "%s%s\n", 1010 imp_mods[i]->imp_mod->mod_info->da_filename, GCOV_DATA_SUFFIX); 1011 } 1012 free (imp_mods); 1013 } 1014 fclose (imports_file); 1015 } 1016} 1017 1018static void 1019gcov_dump_module_info (struct gcov_filename_aux *gf) 1020{ 1021 struct gcov_info *gi_ptr; 1022 1023 /* Compute the module groups and record whether there were any 1024 counter fixups applied that require rewriting the counters. */ 1025 int changed = __gcov_compute_module_groups (); 1026 1027 /* Now write out module group info. */ 1028 for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next) 1029 { 1030 int error; 1031 1032 if (gcov_exit_open_gcda_file (gi_ptr, gf) == -1) 1033 continue; 1034 1035 if (changed) 1036 { 1037 /* Scan file to find the end of the summary section, which is 1038 where we will start re-writing the counters. */ 1039 gcov_position_t summary_end_pos; 1040 if (gcov_scan_summary_end (gi_ptr, &summary_end_pos) == -1) 1041 gcov_error ("profiling:%s:Error scanning summaries\n", 1042 gi_filename); 1043 else 1044 { 1045 gcov_position_t eof_pos = gi_ptr->eof_pos; 1046 gcov_rewrite (); 1047 gcov_seek (summary_end_pos); 1048 gcov_write_func_counters (gi_ptr); 1049 gcc_assert (eof_pos == gi_ptr->eof_pos); 1050 } 1051 } 1052 else 1053 gcov_rewrite (); 1054 1055 /* Overwrite the zero word at the of the file. */ 1056 gcov_seek (gi_ptr->eof_pos); 1057 1058 gcov_write_module_infos (gi_ptr); 1059 /* Write the end marker */ 1060 gcov_write_unsigned (0); 1061 gcov_truncate (); 1062 1063 if ((error = gcov_close ())) 1064 gcov_error (error < 0 ? "profiling:%s:Overflow writing\n" : 1065 "profiling:%s:Error writing\n", 1066 gi_filename); 1067 gcov_write_import_file (gi_filename, gi_ptr); 1068 } 1069 __gcov_finalize_dyn_callgraph (); 1070} 1071 1072/* Dump all the coverage counts for the program. It first computes program 1073 summary and then traverses gcov_list list and dumps the gcov_info 1074 objects one by one. */ 1075 1076void 1077gcov_exit (void) 1078{ 1079 struct gcov_info *gi_ptr; 1080 struct gcov_filename_aux gf; 1081 gcov_unsigned_t crc32; 1082 int dump_module_info = 0; 1083 struct gcov_summary all_prg; 1084 struct gcov_summary this_prg; 1085 1086 /* Prevent the counters from being dumped a second time on exit when the 1087 application already wrote out the profile using __gcov_dump(). */ 1088 if (gcov_dump_complete) 1089 return; 1090 1091 crc32 = gcov_exit_compute_summary (&this_prg); 1092 1093 allocate_filename_struct (&gf); 1094#if !GCOV_LOCKED 1095 memset (&all_prg, 0, sizeof (all_prg)); 1096#endif 1097 1098 /* Now merge each file. */ 1099 for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next) 1100 { 1101 gcov_exit_dump_gcov (gi_ptr, &gf, crc32, &all_prg, &this_prg); 1102 1103 /* The IS_PRIMARY field is overloaded to indicate if this module 1104 is FDO/LIPO. */ 1105 dump_module_info |= gi_ptr->mod_info->is_primary; 1106 } 1107 run_accounted = 1; 1108 1109 if (dump_module_info) 1110 gcov_dump_module_info (&gf); 1111 1112 if (gi_filename) 1113 free (gi_filename); 1114} 1115 1116/* Reset all counters to zero. */ 1117 1118void 1119gcov_clear (void) 1120{ 1121 const struct gcov_info *gi_ptr; 1122 1123 for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next) 1124 { 1125 unsigned f_ix; 1126 1127 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++) 1128 { 1129 unsigned t_ix; 1130 const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix]; 1131 1132 if (!gfi_ptr || gfi_ptr->key != gi_ptr) 1133 continue; 1134 const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs; 1135 for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++) 1136 { 1137 if (!gi_ptr->merge[t_ix]) 1138 continue; 1139 1140 memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num); 1141 ci_ptr++; 1142 } 1143 } 1144 } 1145} 1146 1147/* Add a new object file onto the bb chain. Invoked automatically 1148 when running an object file's global ctors. */ 1149 1150void 1151__gcov_init (struct gcov_info *info) 1152{ 1153#ifndef IN_GCOV_TOOL 1154 if (!gcov_sampling_period_initialized) 1155 { 1156 const char* env_value_str = getenv ("GCOV_SAMPLING_PERIOD"); 1157 if (env_value_str) 1158 { 1159 int env_value_int = atoi(env_value_str); 1160 if (env_value_int >= 1) 1161 __gcov_sampling_period = env_value_int; 1162 } 1163 gcov_sampling_period_initialized = 1; 1164 } 1165#endif 1166 1167 if (!info->version || !info->n_functions) 1168 return; 1169 if (gcov_version (info, info->version, 0)) 1170 { 1171 size_t filename_length = strlen(info->filename); 1172 1173 /* Refresh the longest file name information */ 1174 if (filename_length > gcov_max_filename) 1175 gcov_max_filename = filename_length; 1176 1177 /* Assign the module ID (starting at 1). */ 1178 info->mod_info->ident = (++gcov_cur_module_id); 1179 gcc_assert (EXTRACT_MODULE_ID_FROM_GLOBAL_ID (GEN_FUNC_GLOBAL_ID ( 1180 info->mod_info->ident, 0)) 1181 == info->mod_info->ident); 1182 1183 if (!__gcov_list) 1184 atexit (gcov_exit); 1185 1186 info->next = __gcov_list; 1187 __gcov_list = info; 1188 } 1189 info->version = 0; 1190} 1191 1192#endif /* L_gcov */ 1193#endif /* inhibit_libc */ 1194