1 /* File format for coverage information 2 Copyright (C) 1996-2016 Free Software Foundation, Inc. 3 Contributed by Bob Manson <manson@cygnus.com>. 4 Completely remangled by Nathan Sidwell <nathan@codesourcery.com>. 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free 10 Software Foundation; either version 3, or (at your option) any later 11 version. 12 13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 for more details. 17 18 Under Section 7 of GPL version 3, you are granted additional 19 permissions described in the GCC Runtime Library Exception, version 20 3.1, as published by the Free Software Foundation. 21 22 You should have received a copy of the GNU General Public License and 23 a copy of the GCC Runtime Library Exception along with this program; 24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25 <http://www.gnu.org/licenses/>. */ 26 27 /* Routines declared in gcov-io.h. This file should be #included by 28 another source file, after having #included gcov-io.h. */ 29 30 #if !IN_GCOV 31 static void gcov_write_block (unsigned); 32 static gcov_unsigned_t *gcov_write_words (unsigned); 33 #endif 34 static const gcov_unsigned_t *gcov_read_words (unsigned); 35 #if !IN_LIBGCOV 36 static void gcov_allocate (unsigned); 37 #endif 38 39 /* Optimum number of gcov_unsigned_t's read from or written to disk. */ 40 #define GCOV_BLOCK_SIZE (1 << 10) 41 42 struct gcov_var 43 { 44 FILE *file; 45 gcov_position_t start; /* Position of first byte of block */ 46 unsigned offset; /* Read/write position within the block. */ 47 unsigned length; /* Read limit in the block. */ 48 unsigned overread; /* Number of words overread. */ 49 int error; /* < 0 overflow, > 0 disk error. */ 50 int mode; /* < 0 writing, > 0 reading */ 51 #if IN_LIBGCOV 52 /* Holds one block plus 4 bytes, thus all coverage reads & writes 53 fit within this buffer and we always can transfer GCOV_BLOCK_SIZE 54 to and from the disk. libgcov never backtracks and only writes 4 55 or 8 byte objects. */ 56 gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1]; 57 #else 58 int endian; /* Swap endianness. */ 59 /* Holds a variable length block, as the compiler can write 60 strings and needs to backtrack. */ 61 size_t alloc; 62 gcov_unsigned_t *buffer; 63 #endif 64 } gcov_var; 65 66 /* Save the current position in the gcov file. */ 67 /* We need to expose this function when compiling for gcov-tool. */ 68 #ifndef IN_GCOV_TOOL 69 static inline 70 #endif 71 gcov_position_t 72 gcov_position (void) 73 { 74 gcov_nonruntime_assert (gcov_var.mode > 0); 75 return gcov_var.start + gcov_var.offset; 76 } 77 78 /* Return nonzero if the error flag is set. */ 79 /* We need to expose this function when compiling for gcov-tool. */ 80 #ifndef IN_GCOV_TOOL 81 static inline 82 #endif 83 int 84 gcov_is_error (void) 85 { 86 return gcov_var.file ? gcov_var.error : 1; 87 } 88 89 #if IN_LIBGCOV 90 /* Move to beginning of file and initialize for writing. */ 91 GCOV_LINKAGE inline void 92 gcov_rewrite (void) 93 { 94 gcov_var.mode = -1; 95 gcov_var.start = 0; 96 gcov_var.offset = 0; 97 fseek (gcov_var.file, 0L, SEEK_SET); 98 } 99 #endif 100 101 static inline gcov_unsigned_t from_file (gcov_unsigned_t value) 102 { 103 #if !IN_LIBGCOV 104 if (gcov_var.endian) 105 { 106 value = (value >> 16) | (value << 16); 107 value = ((value & 0xff00ff) << 8) | ((value >> 8) & 0xff00ff); 108 } 109 #endif 110 return value; 111 } 112 113 /* Open a gcov file. NAME is the name of the file to open and MODE 114 indicates whether a new file should be created, or an existing file 115 opened. If MODE is >= 0 an existing file will be opened, if 116 possible, and if MODE is <= 0, a new file will be created. Use 117 MODE=0 to attempt to reopen an existing file and then fall back on 118 creating a new one. If MODE < 0, the file will be opened in 119 read-only mode. Otherwise it will be opened for modification. 120 Return zero on failure, >0 on opening an existing file and <0 on 121 creating a new one. */ 122 123 GCOV_LINKAGE int 124 #if IN_LIBGCOV 125 gcov_open (const char *name) 126 #else 127 gcov_open (const char *name, int mode) 128 #endif 129 { 130 #if IN_LIBGCOV 131 const int mode = 0; 132 #endif 133 #if GCOV_LOCKED 134 struct flock s_flock; 135 int fd; 136 137 s_flock.l_whence = SEEK_SET; 138 s_flock.l_start = 0; 139 s_flock.l_len = 0; /* Until EOF. */ 140 s_flock.l_pid = getpid (); 141 #endif 142 143 gcov_nonruntime_assert (!gcov_var.file); 144 gcov_var.start = 0; 145 gcov_var.offset = gcov_var.length = 0; 146 gcov_var.overread = -1u; 147 gcov_var.error = 0; 148 #if !IN_LIBGCOV 149 gcov_var.endian = 0; 150 #endif 151 #if GCOV_LOCKED 152 if (mode > 0) 153 { 154 /* Read-only mode - acquire a read-lock. */ 155 s_flock.l_type = F_RDLCK; 156 /* pass mode (ignored) for compatibility */ 157 fd = open (name, O_RDONLY, S_IRUSR | S_IWUSR); 158 } 159 else if (mode < 0) 160 { 161 /* Write mode - acquire a write-lock. */ 162 s_flock.l_type = F_WRLCK; 163 fd = open (name, O_RDWR | O_CREAT | O_TRUNC, 0666); 164 } 165 else /* mode == 0 */ 166 { 167 /* Read-Write mode - acquire a write-lock. */ 168 s_flock.l_type = F_WRLCK; 169 fd = open (name, O_RDWR | O_CREAT, 0666); 170 } 171 if (fd < 0) 172 return 0; 173 174 while (fcntl (fd, F_SETLKW, &s_flock) && errno == EINTR) 175 continue; 176 177 gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b"); 178 179 if (!gcov_var.file) 180 { 181 close (fd); 182 return 0; 183 } 184 185 if (mode > 0) 186 gcov_var.mode = 1; 187 else if (mode == 0) 188 { 189 struct stat st; 190 191 if (fstat (fd, &st) < 0) 192 { 193 fclose (gcov_var.file); 194 gcov_var.file = 0; 195 return 0; 196 } 197 if (st.st_size != 0) 198 gcov_var.mode = 1; 199 else 200 gcov_var.mode = mode * 2 + 1; 201 } 202 else 203 gcov_var.mode = mode * 2 + 1; 204 #else 205 if (mode >= 0) 206 gcov_var.file = fopen (name, (mode > 0) ? "rb" : "r+b"); 207 208 if (gcov_var.file) 209 gcov_var.mode = 1; 210 else if (mode <= 0) 211 { 212 gcov_var.file = fopen (name, "w+b"); 213 if (gcov_var.file) 214 gcov_var.mode = mode * 2 + 1; 215 } 216 if (!gcov_var.file) 217 return 0; 218 #endif 219 220 setbuf (gcov_var.file, (char *)0); 221 222 return 1; 223 } 224 225 /* Close the current gcov file. Flushes data to disk. Returns nonzero 226 on failure or error flag set. */ 227 228 GCOV_LINKAGE int 229 gcov_close (void) 230 { 231 if (gcov_var.file) 232 { 233 #if !IN_GCOV 234 if (gcov_var.offset && gcov_var.mode < 0) 235 gcov_write_block (gcov_var.offset); 236 #endif 237 fclose (gcov_var.file); 238 gcov_var.file = 0; 239 gcov_var.length = 0; 240 } 241 #if !IN_LIBGCOV 242 free (gcov_var.buffer); 243 gcov_var.alloc = 0; 244 gcov_var.buffer = 0; 245 #endif 246 gcov_var.mode = 0; 247 return gcov_var.error; 248 } 249 250 #if !IN_LIBGCOV 251 /* Check if MAGIC is EXPECTED. Use it to determine endianness of the 252 file. Returns +1 for same endian, -1 for other endian and zero for 253 not EXPECTED. */ 254 255 GCOV_LINKAGE int 256 gcov_magic (gcov_unsigned_t magic, gcov_unsigned_t expected) 257 { 258 if (magic == expected) 259 return 1; 260 magic = (magic >> 16) | (magic << 16); 261 magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff); 262 if (magic == expected) 263 { 264 gcov_var.endian = 1; 265 return -1; 266 } 267 return 0; 268 } 269 #endif 270 271 #if !IN_LIBGCOV 272 static void 273 gcov_allocate (unsigned length) 274 { 275 size_t new_size = gcov_var.alloc; 276 277 if (!new_size) 278 new_size = GCOV_BLOCK_SIZE; 279 new_size += length; 280 new_size *= 2; 281 282 gcov_var.alloc = new_size; 283 gcov_var.buffer = XRESIZEVAR (gcov_unsigned_t, gcov_var.buffer, new_size << 2); 284 } 285 #endif 286 287 #if !IN_GCOV 288 /* Write out the current block, if needs be. */ 289 290 static void 291 gcov_write_block (unsigned size) 292 { 293 if (fwrite (gcov_var.buffer, size << 2, 1, gcov_var.file) != 1) 294 gcov_var.error = 1; 295 gcov_var.start += size; 296 gcov_var.offset -= size; 297 } 298 299 /* Allocate space to write BYTES bytes to the gcov file. Return a 300 pointer to those bytes, or NULL on failure. */ 301 302 static gcov_unsigned_t * 303 gcov_write_words (unsigned words) 304 { 305 gcov_unsigned_t *result; 306 307 gcov_nonruntime_assert (gcov_var.mode < 0); 308 #if IN_LIBGCOV 309 if (gcov_var.offset >= GCOV_BLOCK_SIZE) 310 { 311 gcov_write_block (GCOV_BLOCK_SIZE); 312 if (gcov_var.offset) 313 { 314 memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4); 315 } 316 } 317 #else 318 if (gcov_var.offset + words > gcov_var.alloc) 319 gcov_allocate (gcov_var.offset + words); 320 #endif 321 result = &gcov_var.buffer[gcov_var.offset]; 322 gcov_var.offset += words; 323 324 return result; 325 } 326 327 /* Write unsigned VALUE to coverage file. Sets error flag 328 appropriately. */ 329 330 GCOV_LINKAGE void 331 gcov_write_unsigned (gcov_unsigned_t value) 332 { 333 gcov_unsigned_t *buffer = gcov_write_words (1); 334 335 buffer[0] = value; 336 } 337 338 /* Write counter VALUE to coverage file. Sets error flag 339 appropriately. */ 340 341 #if IN_LIBGCOV 342 GCOV_LINKAGE void 343 gcov_write_counter (gcov_type value) 344 { 345 gcov_unsigned_t *buffer = gcov_write_words (2); 346 347 buffer[0] = (gcov_unsigned_t) value; 348 if (sizeof (value) > sizeof (gcov_unsigned_t)) 349 buffer[1] = (gcov_unsigned_t) (value >> 32); 350 else 351 buffer[1] = 0; 352 } 353 #endif /* IN_LIBGCOV */ 354 355 #if !IN_LIBGCOV 356 /* Write STRING to coverage file. Sets error flag on file 357 error, overflow flag on overflow */ 358 359 GCOV_LINKAGE void 360 gcov_write_string (const char *string) 361 { 362 unsigned length = 0; 363 unsigned alloc = 0; 364 gcov_unsigned_t *buffer; 365 366 if (string) 367 { 368 length = strlen (string); 369 alloc = (length + 4) >> 2; 370 } 371 372 buffer = gcov_write_words (1 + alloc); 373 374 buffer[0] = alloc; 375 376 if (alloc > 0) 377 { 378 buffer[alloc] = 0; /* place nul terminators. */ 379 memcpy (&buffer[1], string, length); 380 } 381 } 382 #endif 383 384 #if !IN_LIBGCOV 385 /* Write a tag TAG and reserve space for the record length. Return a 386 value to be used for gcov_write_length. */ 387 388 GCOV_LINKAGE gcov_position_t 389 gcov_write_tag (gcov_unsigned_t tag) 390 { 391 gcov_position_t result = gcov_var.start + gcov_var.offset; 392 gcov_unsigned_t *buffer = gcov_write_words (2); 393 394 buffer[0] = tag; 395 buffer[1] = 0; 396 397 return result; 398 } 399 400 /* Write a record length using POSITION, which was returned by 401 gcov_write_tag. The current file position is the end of the 402 record, and is restored before returning. Returns nonzero on 403 overflow. */ 404 405 GCOV_LINKAGE void 406 gcov_write_length (gcov_position_t position) 407 { 408 unsigned offset; 409 gcov_unsigned_t length; 410 gcov_unsigned_t *buffer; 411 412 gcov_nonruntime_assert (gcov_var.mode < 0); 413 gcov_nonruntime_assert (position + 2 <= gcov_var.start + gcov_var.offset); 414 gcov_nonruntime_assert (position >= gcov_var.start); 415 offset = position - gcov_var.start; 416 length = gcov_var.offset - offset - 2; 417 buffer = (gcov_unsigned_t *) &gcov_var.buffer[offset]; 418 buffer[1] = length; 419 if (gcov_var.offset >= GCOV_BLOCK_SIZE) 420 gcov_write_block (gcov_var.offset); 421 } 422 423 #else /* IN_LIBGCOV */ 424 425 /* Write a tag TAG and length LENGTH. */ 426 427 GCOV_LINKAGE void 428 gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length) 429 { 430 gcov_unsigned_t *buffer = gcov_write_words (2); 431 432 buffer[0] = tag; 433 buffer[1] = length; 434 } 435 436 /* Write a summary structure to the gcov file. Return nonzero on 437 overflow. */ 438 439 GCOV_LINKAGE void 440 gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary) 441 { 442 unsigned ix, h_ix, bv_ix, h_cnt = 0; 443 const struct gcov_ctr_summary *csum; 444 unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; 445 446 /* Count number of non-zero histogram entries, and fill in a bit vector 447 of non-zero indices. The histogram is only currently computed for arc 448 counters. */ 449 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 450 histo_bitvector[bv_ix] = 0; 451 csum = &summary->ctrs[GCOV_COUNTER_ARCS]; 452 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) 453 { 454 if (csum->histogram[h_ix].num_counters > 0) 455 { 456 histo_bitvector[h_ix / 32] |= 1 << (h_ix % 32); 457 h_cnt++; 458 } 459 } 460 gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH (h_cnt)); 461 gcov_write_unsigned (summary->checksum); 462 for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) 463 { 464 gcov_write_unsigned (csum->num); 465 gcov_write_unsigned (csum->runs); 466 gcov_write_counter (csum->sum_all); 467 gcov_write_counter (csum->run_max); 468 gcov_write_counter (csum->sum_max); 469 if (ix != GCOV_COUNTER_ARCS) 470 { 471 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 472 gcov_write_unsigned (0); 473 continue; 474 } 475 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 476 gcov_write_unsigned (histo_bitvector[bv_ix]); 477 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) 478 { 479 if (!csum->histogram[h_ix].num_counters) 480 continue; 481 gcov_write_unsigned (csum->histogram[h_ix].num_counters); 482 gcov_write_counter (csum->histogram[h_ix].min_value); 483 gcov_write_counter (csum->histogram[h_ix].cum_value); 484 } 485 } 486 } 487 #endif /* IN_LIBGCOV */ 488 489 #endif /*!IN_GCOV */ 490 491 /* Return a pointer to read BYTES bytes from the gcov file. Returns 492 NULL on failure (read past EOF). */ 493 494 static const gcov_unsigned_t * 495 gcov_read_words (unsigned words) 496 { 497 const gcov_unsigned_t *result; 498 unsigned excess = gcov_var.length - gcov_var.offset; 499 500 gcov_nonruntime_assert (gcov_var.mode > 0); 501 if (excess < words) 502 { 503 gcov_var.start += gcov_var.offset; 504 if (excess) 505 { 506 #if IN_LIBGCOV 507 memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4); 508 #else 509 memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 510 excess * 4); 511 #endif 512 } 513 gcov_var.offset = 0; 514 gcov_var.length = excess; 515 #if IN_LIBGCOV 516 excess = GCOV_BLOCK_SIZE; 517 #else 518 if (gcov_var.length + words > gcov_var.alloc) 519 gcov_allocate (gcov_var.length + words); 520 excess = gcov_var.alloc - gcov_var.length; 521 #endif 522 excess = fread (gcov_var.buffer + gcov_var.length, 523 1, excess << 2, gcov_var.file) >> 2; 524 gcov_var.length += excess; 525 if (gcov_var.length < words) 526 { 527 gcov_var.overread += words - gcov_var.length; 528 gcov_var.length = 0; 529 return 0; 530 } 531 } 532 result = &gcov_var.buffer[gcov_var.offset]; 533 gcov_var.offset += words; 534 return result; 535 } 536 537 /* Read unsigned value from a coverage file. Sets error flag on file 538 error, overflow flag on overflow */ 539 540 GCOV_LINKAGE gcov_unsigned_t 541 gcov_read_unsigned (void) 542 { 543 gcov_unsigned_t value; 544 const gcov_unsigned_t *buffer = gcov_read_words (1); 545 546 if (!buffer) 547 return 0; 548 value = from_file (buffer[0]); 549 return value; 550 } 551 552 /* Read counter value from a coverage file. Sets error flag on file 553 error, overflow flag on overflow */ 554 555 GCOV_LINKAGE gcov_type 556 gcov_read_counter (void) 557 { 558 gcov_type value; 559 const gcov_unsigned_t *buffer = gcov_read_words (2); 560 561 if (!buffer) 562 return 0; 563 value = from_file (buffer[0]); 564 if (sizeof (value) > sizeof (gcov_unsigned_t)) 565 value |= ((gcov_type) from_file (buffer[1])) << 32; 566 else if (buffer[1]) 567 gcov_var.error = -1; 568 569 return value; 570 } 571 572 /* We need to expose the below function when compiling for gcov-tool. */ 573 574 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL) 575 /* Read string from coverage file. Returns a pointer to a static 576 buffer, or NULL on empty string. You must copy the string before 577 calling another gcov function. */ 578 579 GCOV_LINKAGE const char * 580 gcov_read_string (void) 581 { 582 unsigned length = gcov_read_unsigned (); 583 584 if (!length) 585 return 0; 586 587 return (const char *) gcov_read_words (length); 588 } 589 #endif 590 591 GCOV_LINKAGE void 592 gcov_read_summary (struct gcov_summary *summary) 593 { 594 unsigned ix, h_ix, bv_ix, h_cnt = 0; 595 struct gcov_ctr_summary *csum; 596 unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; 597 unsigned cur_bitvector; 598 599 summary->checksum = gcov_read_unsigned (); 600 for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) 601 { 602 csum->num = gcov_read_unsigned (); 603 csum->runs = gcov_read_unsigned (); 604 csum->sum_all = gcov_read_counter (); 605 csum->run_max = gcov_read_counter (); 606 csum->sum_max = gcov_read_counter (); 607 memset (csum->histogram, 0, 608 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); 609 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 610 { 611 histo_bitvector[bv_ix] = gcov_read_unsigned (); 612 #if IN_LIBGCOV 613 /* When building libgcov we don't include system.h, which includes 614 hwint.h (where popcount_hwi is declared). However, libgcov.a 615 is built by the bootstrapped compiler and therefore the builtins 616 are always available. */ 617 h_cnt += __builtin_popcount (histo_bitvector[bv_ix]); 618 #else 619 h_cnt += popcount_hwi (histo_bitvector[bv_ix]); 620 #endif 621 } 622 bv_ix = 0; 623 h_ix = 0; 624 cur_bitvector = 0; 625 while (h_cnt--) 626 { 627 /* Find the index corresponding to the next entry we will read in. 628 First find the next non-zero bitvector and re-initialize 629 the histogram index accordingly, then right shift and increment 630 the index until we find a set bit. */ 631 while (!cur_bitvector) 632 { 633 h_ix = bv_ix * 32; 634 if (bv_ix >= GCOV_HISTOGRAM_BITVECTOR_SIZE) 635 gcov_error ("corrupted profile info: summary histogram " 636 "bitvector is corrupt"); 637 cur_bitvector = histo_bitvector[bv_ix++]; 638 } 639 while (!(cur_bitvector & 0x1)) 640 { 641 h_ix++; 642 cur_bitvector >>= 1; 643 } 644 if (h_ix >= GCOV_HISTOGRAM_SIZE) 645 gcov_error ("corrupted profile info: summary histogram " 646 "index is corrupt"); 647 648 csum->histogram[h_ix].num_counters = gcov_read_unsigned (); 649 csum->histogram[h_ix].min_value = gcov_read_counter (); 650 csum->histogram[h_ix].cum_value = gcov_read_counter (); 651 /* Shift off the index we are done with and increment to the 652 corresponding next histogram entry. */ 653 cur_bitvector >>= 1; 654 h_ix++; 655 } 656 } 657 } 658 659 /* We need to expose the below function when compiling for gcov-tool. */ 660 661 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL) 662 /* Reset to a known position. BASE should have been obtained from 663 gcov_position, LENGTH should be a record length. */ 664 665 GCOV_LINKAGE void 666 gcov_sync (gcov_position_t base, gcov_unsigned_t length) 667 { 668 gcov_nonruntime_assert (gcov_var.mode > 0); 669 base += length; 670 if (base - gcov_var.start <= gcov_var.length) 671 gcov_var.offset = base - gcov_var.start; 672 else 673 { 674 gcov_var.offset = gcov_var.length = 0; 675 fseek (gcov_var.file, base << 2, SEEK_SET); 676 gcov_var.start = ftell (gcov_var.file) >> 2; 677 } 678 } 679 #endif 680 681 #if IN_LIBGCOV 682 /* Move to a given position in a gcov file. */ 683 684 GCOV_LINKAGE void 685 gcov_seek (gcov_position_t base) 686 { 687 if (gcov_var.offset) 688 gcov_write_block (gcov_var.offset); 689 fseek (gcov_var.file, base << 2, SEEK_SET); 690 gcov_var.start = ftell (gcov_var.file) >> 2; 691 } 692 #endif 693 694 #if IN_GCOV > 0 695 /* Return the modification time of the current gcov file. */ 696 697 GCOV_LINKAGE time_t 698 gcov_time (void) 699 { 700 struct stat status; 701 702 if (fstat (fileno (gcov_var.file), &status)) 703 return 0; 704 else 705 return status.st_mtime; 706 } 707 #endif /* IN_GCOV */ 708 709 #if !IN_GCOV 710 /* Determine the index into histogram for VALUE. */ 711 712 #if IN_LIBGCOV 713 static unsigned 714 #else 715 GCOV_LINKAGE unsigned 716 #endif 717 gcov_histo_index (gcov_type value) 718 { 719 gcov_type_unsigned v = (gcov_type_unsigned)value; 720 unsigned r = 0; 721 unsigned prev2bits = 0; 722 723 /* Find index into log2 scale histogram, where each of the log2 724 sized buckets is divided into 4 linear sub-buckets for better 725 focus in the higher buckets. */ 726 727 /* Find the place of the most-significant bit set. */ 728 if (v > 0) 729 { 730 #if IN_LIBGCOV 731 /* When building libgcov we don't include system.h, which includes 732 hwint.h (where floor_log2 is declared). However, libgcov.a 733 is built by the bootstrapped compiler and therefore the builtins 734 are always available. */ 735 r = sizeof (long long) * __CHAR_BIT__ - 1 - __builtin_clzll (v); 736 #else 737 /* We use floor_log2 from hwint.c, which takes a HOST_WIDE_INT 738 that is 64 bits and gcov_type_unsigned is 64 bits. */ 739 r = floor_log2 (v); 740 #endif 741 } 742 743 /* If at most the 2 least significant bits are set (value is 744 0 - 3) then that value is our index into the lowest set of 745 four buckets. */ 746 if (r < 2) 747 return (unsigned)value; 748 749 gcov_nonruntime_assert (r < 64); 750 751 /* Find the two next most significant bits to determine which 752 of the four linear sub-buckets to select. */ 753 prev2bits = (v >> (r - 2)) & 0x3; 754 /* Finally, compose the final bucket index from the log2 index and 755 the next 2 bits. The minimum r value at this point is 2 since we 756 returned above if r was 2 or more, so the minimum bucket at this 757 point is 4. */ 758 return (r - 1) * 4 + prev2bits; 759 } 760 761 /* Merge SRC_HISTO into TGT_HISTO. The counters are assumed to be in 762 the same relative order in both histograms, and are matched up 763 and merged in reverse order. Each counter is assigned an equal portion of 764 its entry's original cumulative counter value when computing the 765 new merged cum_value. */ 766 767 static void gcov_histogram_merge (gcov_bucket_type *tgt_histo, 768 gcov_bucket_type *src_histo) 769 { 770 int src_i, tgt_i, tmp_i = 0; 771 unsigned src_num, tgt_num, merge_num; 772 gcov_type src_cum, tgt_cum, merge_src_cum, merge_tgt_cum, merge_cum; 773 gcov_type merge_min; 774 gcov_bucket_type tmp_histo[GCOV_HISTOGRAM_SIZE]; 775 int src_done = 0; 776 777 memset (tmp_histo, 0, sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); 778 779 /* Assume that the counters are in the same relative order in both 780 histograms. Walk the histograms from largest to smallest entry, 781 matching up and combining counters in order. */ 782 src_num = 0; 783 src_cum = 0; 784 src_i = GCOV_HISTOGRAM_SIZE - 1; 785 for (tgt_i = GCOV_HISTOGRAM_SIZE - 1; tgt_i >= 0 && !src_done; tgt_i--) 786 { 787 tgt_num = tgt_histo[tgt_i].num_counters; 788 tgt_cum = tgt_histo[tgt_i].cum_value; 789 /* Keep going until all of the target histogram's counters at this 790 position have been matched and merged with counters from the 791 source histogram. */ 792 while (tgt_num > 0 && !src_done) 793 { 794 /* If this is either the first time through this loop or we just 795 exhausted the previous non-zero source histogram entry, look 796 for the next non-zero source histogram entry. */ 797 if (!src_num) 798 { 799 /* Locate the next non-zero entry. */ 800 while (src_i >= 0 && !src_histo[src_i].num_counters) 801 src_i--; 802 /* If source histogram has fewer counters, then just copy over the 803 remaining target counters and quit. */ 804 if (src_i < 0) 805 { 806 tmp_histo[tgt_i].num_counters += tgt_num; 807 tmp_histo[tgt_i].cum_value += tgt_cum; 808 if (!tmp_histo[tgt_i].min_value || 809 tgt_histo[tgt_i].min_value < tmp_histo[tgt_i].min_value) 810 tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value; 811 while (--tgt_i >= 0) 812 { 813 tmp_histo[tgt_i].num_counters 814 += tgt_histo[tgt_i].num_counters; 815 tmp_histo[tgt_i].cum_value += tgt_histo[tgt_i].cum_value; 816 if (!tmp_histo[tgt_i].min_value || 817 tgt_histo[tgt_i].min_value 818 < tmp_histo[tgt_i].min_value) 819 tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value; 820 } 821 822 src_done = 1; 823 break; 824 } 825 826 src_num = src_histo[src_i].num_counters; 827 src_cum = src_histo[src_i].cum_value; 828 } 829 830 /* The number of counters to merge on this pass is the minimum 831 of the remaining counters from the current target and source 832 histogram entries. */ 833 merge_num = tgt_num; 834 if (src_num < merge_num) 835 merge_num = src_num; 836 837 /* The merged min_value is the sum of the min_values from target 838 and source. */ 839 merge_min = tgt_histo[tgt_i].min_value + src_histo[src_i].min_value; 840 841 /* Compute the portion of source and target entries' cum_value 842 that will be apportioned to the counters being merged. 843 The total remaining cum_value from each entry is divided 844 equally among the counters from that histogram entry if we 845 are not merging all of them. */ 846 merge_src_cum = src_cum; 847 if (merge_num < src_num) 848 merge_src_cum = merge_num * src_cum / src_num; 849 merge_tgt_cum = tgt_cum; 850 if (merge_num < tgt_num) 851 merge_tgt_cum = merge_num * tgt_cum / tgt_num; 852 /* The merged cum_value is the sum of the source and target 853 components. */ 854 merge_cum = merge_src_cum + merge_tgt_cum; 855 856 /* Update the remaining number of counters and cum_value left 857 to be merged from this source and target entry. */ 858 src_cum -= merge_src_cum; 859 tgt_cum -= merge_tgt_cum; 860 src_num -= merge_num; 861 tgt_num -= merge_num; 862 863 /* The merged counters get placed in the new merged histogram 864 at the entry for the merged min_value. */ 865 tmp_i = gcov_histo_index (merge_min); 866 gcov_nonruntime_assert (tmp_i < GCOV_HISTOGRAM_SIZE); 867 tmp_histo[tmp_i].num_counters += merge_num; 868 tmp_histo[tmp_i].cum_value += merge_cum; 869 if (!tmp_histo[tmp_i].min_value || 870 merge_min < tmp_histo[tmp_i].min_value) 871 tmp_histo[tmp_i].min_value = merge_min; 872 873 /* Ensure the search for the next non-zero src_histo entry starts 874 at the next smallest histogram bucket. */ 875 if (!src_num) 876 src_i--; 877 } 878 } 879 880 gcov_nonruntime_assert (tgt_i < 0); 881 882 /* In the case where there were more counters in the source histogram, 883 accumulate the remaining unmerged cumulative counter values. Add 884 those to the smallest non-zero target histogram entry. Otherwise, 885 the total cumulative counter values in the histogram will be smaller 886 than the sum_all stored in the summary, which will complicate 887 computing the working set information from the histogram later on. */ 888 if (src_num) 889 src_i--; 890 while (src_i >= 0) 891 { 892 src_cum += src_histo[src_i].cum_value; 893 src_i--; 894 } 895 /* At this point, tmp_i should be the smallest non-zero entry in the 896 tmp_histo. */ 897 gcov_nonruntime_assert (tmp_i >= 0 && tmp_i < GCOV_HISTOGRAM_SIZE 898 && tmp_histo[tmp_i].num_counters > 0); 899 tmp_histo[tmp_i].cum_value += src_cum; 900 901 /* Finally, copy the merged histogram into tgt_histo. */ 902 memcpy (tgt_histo, tmp_histo, 903 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); 904 } 905 #endif /* !IN_GCOV */ 906 907 /* This is used by gcov-dump (IN_GCOV == -1) and in the compiler 908 (!IN_GCOV && !IN_LIBGCOV). */ 909 #if IN_GCOV <= 0 && !IN_LIBGCOV 910 /* Compute the working set information from the counter histogram in 911 the profile summary. This is an array of information corresponding to a 912 range of percentages of the total execution count (sum_all), and includes 913 the number of counters required to cover that working set percentage and 914 the minimum counter value in that working set. */ 915 916 GCOV_LINKAGE void 917 compute_working_sets (const struct gcov_ctr_summary *summary, 918 gcov_working_set_t *gcov_working_sets) 919 { 920 gcov_type working_set_cum_values[NUM_GCOV_WORKING_SETS]; 921 gcov_type ws_cum_hotness_incr; 922 gcov_type cum, tmp_cum; 923 const gcov_bucket_type *histo_bucket; 924 unsigned ws_ix, c_num, count; 925 int h_ix; 926 927 /* Compute the amount of sum_all that the cumulative hotness grows 928 by in each successive working set entry, which depends on the 929 number of working set entries. */ 930 ws_cum_hotness_incr = summary->sum_all / NUM_GCOV_WORKING_SETS; 931 932 /* Next fill in an array of the cumulative hotness values corresponding 933 to each working set summary entry we are going to compute below. 934 Skip 0% statistics, which can be extrapolated from the 935 rest of the summary data. */ 936 cum = ws_cum_hotness_incr; 937 for (ws_ix = 0; ws_ix < NUM_GCOV_WORKING_SETS; 938 ws_ix++, cum += ws_cum_hotness_incr) 939 working_set_cum_values[ws_ix] = cum; 940 /* The last summary entry is reserved for (roughly) 99.9% of the 941 working set. Divide by 1024 so it becomes a shift, which gives 942 almost exactly 99.9%. */ 943 working_set_cum_values[NUM_GCOV_WORKING_SETS-1] 944 = summary->sum_all - summary->sum_all/1024; 945 946 /* Next, walk through the histogram in decending order of hotness 947 and compute the statistics for the working set summary array. 948 As histogram entries are accumulated, we check to see which 949 working set entries have had their expected cum_value reached 950 and fill them in, walking the working set entries in increasing 951 size of cum_value. */ 952 ws_ix = 0; /* The current entry into the working set array. */ 953 cum = 0; /* The current accumulated counter sum. */ 954 count = 0; /* The current accumulated count of block counters. */ 955 for (h_ix = GCOV_HISTOGRAM_SIZE - 1; 956 h_ix >= 0 && ws_ix < NUM_GCOV_WORKING_SETS; h_ix--) 957 { 958 histo_bucket = &summary->histogram[h_ix]; 959 960 /* If we haven't reached the required cumulative counter value for 961 the current working set percentage, simply accumulate this histogram 962 entry into the running sums and continue to the next histogram 963 entry. */ 964 if (cum + histo_bucket->cum_value < working_set_cum_values[ws_ix]) 965 { 966 cum += histo_bucket->cum_value; 967 count += histo_bucket->num_counters; 968 continue; 969 } 970 971 /* If adding the current histogram entry's cumulative counter value 972 causes us to exceed the current working set size, then estimate 973 how many of this histogram entry's counter values are required to 974 reach the working set size, and fill in working set entries 975 as we reach their expected cumulative value. */ 976 for (c_num = 0, tmp_cum = cum; 977 c_num < histo_bucket->num_counters && ws_ix < NUM_GCOV_WORKING_SETS; 978 c_num++) 979 { 980 count++; 981 /* If we haven't reached the last histogram entry counter, add 982 in the minimum value again. This will underestimate the 983 cumulative sum so far, because many of the counter values in this 984 entry may have been larger than the minimum. We could add in the 985 average value every time, but that would require an expensive 986 divide operation. */ 987 if (c_num + 1 < histo_bucket->num_counters) 988 tmp_cum += histo_bucket->min_value; 989 /* If we have reached the last histogram entry counter, then add 990 in the entire cumulative value. */ 991 else 992 tmp_cum = cum + histo_bucket->cum_value; 993 994 /* Next walk through successive working set entries and fill in 995 the statistics for any whose size we have reached by accumulating 996 this histogram counter. */ 997 while (ws_ix < NUM_GCOV_WORKING_SETS 998 && tmp_cum >= working_set_cum_values[ws_ix]) 999 { 1000 gcov_working_sets[ws_ix].num_counters = count; 1001 gcov_working_sets[ws_ix].min_counter 1002 = histo_bucket->min_value; 1003 ws_ix++; 1004 } 1005 } 1006 /* Finally, update the running cumulative value since we were 1007 using a temporary above. */ 1008 cum += histo_bucket->cum_value; 1009 } 1010 gcov_nonruntime_assert (ws_ix == NUM_GCOV_WORKING_SETS); 1011 } 1012 #endif /* IN_GCOV <= 0 && !IN_LIBGCOV */ 1013