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