1/* File format for coverage information 2 Copyright (C) 1996-2014 Free Software Foundation, Inc. 3 Contributed by Bob Manson <manson@cygnus.com>. 4 Completely remangled by Nathan Sidwell <nathan@codesourcery.com>. 5 6This file is part of GCC. 7 8GCC is free software; you can redistribute it and/or modify it under 9the terms of the GNU General Public License as published by the Free 10Software Foundation; either version 3, or (at your option) any later 11version. 12 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14WARRANTY; without even the implied warranty of MERCHANTABILITY or 15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16for more details. 17 18Under Section 7 of GPL version 3, you are granted additional 19permissions described in the GCC Runtime Library Exception, version 203.1, as published by the Free Software Foundation. 21 22You should have received a copy of the GNU General Public License and 23a copy of the GCC Runtime Library Exception along with this program; 24see 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 31static void gcov_write_block (unsigned); 32static gcov_unsigned_t *gcov_write_words (unsigned); 33#endif 34static const gcov_unsigned_t *gcov_read_words (unsigned); 35#if !IN_LIBGCOV 36static 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 42GCOV_LINKAGE struct gcov_var 43{ 44 _GCOV_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 69static inline 70#endif 71gcov_position_t 72gcov_position (void) 73{ 74 return gcov_var.start + gcov_var.offset; 75} 76 77/* Return nonzero if the error flag is set. */ 78/* We need to expose this function when compiling for gcov-tool. */ 79#ifndef IN_GCOV_TOOL 80static inline 81#endif 82int 83gcov_is_error (void) 84{ 85 return gcov_var.file ? gcov_var.error : 1; 86} 87 88#if IN_LIBGCOV 89/* Move to beginning of file and initialize for writing. */ 90GCOV_LINKAGE inline void 91gcov_rewrite (void) 92{ 93 gcc_assert (gcov_var.mode > 0); 94 gcov_var.mode = -1; 95 gcov_var.start = 0; 96 gcov_var.offset = 0; 97 _GCOV_fseek (gcov_var.file, 0L, SEEK_SET); 98} 99#endif 100 101static 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#ifndef __KERNEL__ 124GCOV_LINKAGE int 125#if IN_LIBGCOV 126gcov_open (const char *name) 127#else 128gcov_open (const char *name, int mode) 129#endif 130{ 131#if IN_LIBGCOV 132 const int mode = 0; 133#endif 134#if GCOV_LOCKED 135 struct flock s_flock; 136 int fd; 137 138 s_flock.l_whence = SEEK_SET; 139 s_flock.l_start = 0; 140 s_flock.l_len = 0; /* Until EOF. */ 141 s_flock.l_pid = getpid (); 142#endif 143 144 gcc_assert (!gcov_var.file); 145 gcov_var.start = 0; 146 gcov_var.offset = gcov_var.length = 0; 147 gcov_var.overread = -1u; 148 gcov_var.error = 0; 149#if !IN_LIBGCOV 150 gcov_var.endian = 0; 151#endif 152#if GCOV_LOCKED 153 if (mode > 0) 154 { 155 /* Read-only mode - acquire a read-lock. */ 156 s_flock.l_type = F_RDLCK; 157 /* pass mode (ignored) for compatibility */ 158 fd = open (name, O_RDONLY, S_IRUSR | S_IWUSR); 159 } 160 else if (mode < 0) 161 { 162 /* Write mode - acquire a write-lock. */ 163 s_flock.l_type = F_WRLCK; 164 fd = open (name, O_RDWR | O_CREAT | O_TRUNC, 0666); 165 } 166 else /* mode == 0 */ 167 { 168 /* Read-Write mode - acquire a write-lock. */ 169 s_flock.l_type = F_WRLCK; 170 fd = open (name, O_RDWR | O_CREAT, 0666); 171 } 172 if (fd < 0) 173 return 0; 174 175 while (fcntl (fd, F_SETLKW, &s_flock) && errno == EINTR) 176 continue; 177 178 gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b"); 179 180 if (!gcov_var.file) 181 { 182 close (fd); 183 return 0; 184 } 185 186 if (mode > 0) 187 gcov_var.mode = 1; 188 else if (mode == 0) 189 { 190 struct stat st; 191 192 if (fstat (fd, &st) < 0) 193 { 194 _GCOV_fclose (gcov_var.file); 195 gcov_var.file = 0; 196 return 0; 197 } 198 if (st.st_size != 0) 199 gcov_var.mode = 1; 200 else 201 gcov_var.mode = mode * 2 + 1; 202 } 203 else 204 gcov_var.mode = mode * 2 + 1; 205#else 206 if (mode >= 0) 207 gcov_var.file = _GCOV_fopen (name, (mode > 0) ? "rb" : "r+b"); 208 209 if (gcov_var.file) 210 gcov_var.mode = 1; 211 else if (mode <= 0) 212 { 213 gcov_var.file = _GCOV_fopen (name, "w+b"); 214 if (gcov_var.file) 215 gcov_var.mode = mode * 2 + 1; 216 } 217 if (!gcov_var.file) 218 return 0; 219#endif 220 221 setbuf (gcov_var.file, (char *)0); 222 223 return 1; 224} 225#else /* __KERNEL__ */ 226 227extern _GCOV_FILE *gcov_current_file; 228 229GCOV_LINKAGE int 230gcov_open (const char *name) 231{ 232 gcov_var.start = 0; 233 gcov_var.offset = gcov_var.length = 0; 234 gcov_var.overread = -1u; 235 gcov_var.error = 0; 236 gcov_var.file = gcov_current_file; 237 gcov_var.mode = 1; 238 239 return 1; 240} 241#endif /* __KERNEL__ */ 242 243 244/* Close the current gcov file. Flushes data to disk. Returns nonzero 245 on failure or error flag set. */ 246 247GCOV_LINKAGE int 248gcov_close (void) 249{ 250 if (gcov_var.file) 251 { 252#if !IN_GCOV 253 if (gcov_var.offset && gcov_var.mode < 0) 254 gcov_write_block (gcov_var.offset); 255#endif 256 _GCOV_fclose (gcov_var.file); 257 gcov_var.file = 0; 258 gcov_var.length = 0; 259 } 260#if !IN_LIBGCOV 261 free (gcov_var.buffer); 262 gcov_var.alloc = 0; 263 gcov_var.buffer = 0; 264#endif 265 gcov_var.mode = 0; 266 return gcov_var.error; 267} 268 269#if !IN_LIBGCOV 270/* Check if MAGIC is EXPECTED. Use it to determine endianness of the 271 file. Returns +1 for same endian, -1 for other endian and zero for 272 not EXPECTED. */ 273 274GCOV_LINKAGE int 275gcov_magic (gcov_unsigned_t magic, gcov_unsigned_t expected) 276{ 277 if (magic == expected) 278 return 1; 279 magic = (magic >> 16) | (magic << 16); 280 magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff); 281 if (magic == expected) 282 { 283 gcov_var.endian = 1; 284 return -1; 285 } 286 return 0; 287} 288#endif 289 290#if !IN_LIBGCOV 291static void 292gcov_allocate (unsigned length) 293{ 294 size_t new_size = gcov_var.alloc; 295 296 if (!new_size) 297 new_size = GCOV_BLOCK_SIZE; 298 new_size += length; 299 new_size *= 2; 300 301 gcov_var.alloc = new_size; 302 gcov_var.buffer = XRESIZEVAR (gcov_unsigned_t, gcov_var.buffer, new_size << 2); 303} 304#endif 305 306#if !IN_GCOV 307/* Write out the current block, if needs be. */ 308 309static void 310gcov_write_block (unsigned size) 311{ 312 if (_GCOV_fwrite (gcov_var.buffer, size << 2, 1, gcov_var.file) != 1) 313 gcov_var.error = 1; 314 gcov_var.start += size; 315 gcov_var.offset -= size; 316} 317 318/* Allocate space to write BYTES bytes to the gcov file. Return a 319 pointer to those bytes, or NULL on failure. */ 320 321static gcov_unsigned_t * 322gcov_write_words (unsigned words) 323{ 324 gcov_unsigned_t *result; 325 326 gcc_assert (gcov_var.mode < 0); 327#if IN_LIBGCOV 328 if (gcov_var.offset >= GCOV_BLOCK_SIZE) 329 { 330 gcov_write_block (GCOV_BLOCK_SIZE); 331 if (gcov_var.offset) 332 { 333 gcc_assert (gcov_var.offset == 1); 334 memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4); 335 } 336 } 337#else 338 if (gcov_var.offset + words > gcov_var.alloc) 339 gcov_allocate (gcov_var.offset + words); 340#endif 341 result = &gcov_var.buffer[gcov_var.offset]; 342 gcov_var.offset += words; 343 344 return result; 345} 346 347/* Write unsigned VALUE to coverage file. Sets error flag 348 appropriately. */ 349 350GCOV_LINKAGE void 351gcov_write_unsigned (gcov_unsigned_t value) 352{ 353 gcov_unsigned_t *buffer = gcov_write_words (1); 354 355 buffer[0] = value; 356} 357 358/* Compute the total length in words required to write NUM_STRINGS 359 in STRING_ARRAY as unsigned. */ 360 361GCOV_LINKAGE gcov_unsigned_t 362gcov_compute_string_array_len (char **string_array, 363 gcov_unsigned_t num_strings) 364{ 365 gcov_unsigned_t len = 0, i; 366 for (i = 0; i < num_strings; i++) 367 { 368 gcov_unsigned_t string_len 369 = (strlen (string_array[i]) + sizeof (gcov_unsigned_t)) 370 / sizeof (gcov_unsigned_t); 371 len += string_len; 372 len += 1; /* Each string is lead by a length. */ 373 } 374 return len; 375} 376 377/* Write NUM_STRINGS in STRING_ARRAY as unsigned. */ 378 379GCOV_LINKAGE void 380gcov_write_string_array (char **string_array, gcov_unsigned_t num_strings) 381{ 382 gcov_unsigned_t i, j; 383 for (j = 0; j < num_strings; j++) 384 { 385 gcov_unsigned_t *aligned_string; 386 gcov_unsigned_t string_len = 387 (strlen (string_array[j]) + sizeof (gcov_unsigned_t)) / 388 sizeof (gcov_unsigned_t); 389 aligned_string = (gcov_unsigned_t *) 390 alloca ((string_len + 1) * sizeof (gcov_unsigned_t)); 391 memset (aligned_string, 0, (string_len + 1) * sizeof (gcov_unsigned_t)); 392 aligned_string[0] = string_len; 393 strcpy ((char*) (aligned_string + 1), string_array[j]); 394 for (i = 0; i < (string_len + 1); i++) 395 gcov_write_unsigned (aligned_string[i]); 396 } 397} 398 399/* Write counter VALUE to coverage file. Sets error flag 400 appropriately. */ 401 402#if IN_LIBGCOV 403GCOV_LINKAGE void 404gcov_write_counter (gcov_type value) 405{ 406 gcov_unsigned_t *buffer = gcov_write_words (2); 407 408 buffer[0] = (gcov_unsigned_t) value; 409 if (sizeof (value) > sizeof (gcov_unsigned_t)) 410 buffer[1] = (gcov_unsigned_t) (value >> 32); 411 else 412 buffer[1] = 0; 413} 414#endif /* IN_LIBGCOV */ 415 416#if !IN_LIBGCOV 417/* Write STRING to coverage file. Sets error flag on file 418 error, overflow flag on overflow */ 419 420GCOV_LINKAGE void 421gcov_write_string (const char *string) 422{ 423 unsigned length = 0; 424 unsigned alloc = 0; 425 gcov_unsigned_t *buffer; 426 427 if (string) 428 { 429 length = strlen (string); 430 alloc = (length + 4) >> 2; 431 } 432 433 buffer = gcov_write_words (1 + alloc); 434 435 buffer[0] = alloc; 436 buffer[alloc] = 0; 437 memcpy (&buffer[1], string, length); 438} 439#endif 440 441#if !IN_LIBGCOV 442/* Write a tag TAG and reserve space for the record length. Return a 443 value to be used for gcov_write_length. */ 444 445GCOV_LINKAGE gcov_position_t 446gcov_write_tag (gcov_unsigned_t tag) 447{ 448 gcov_position_t result = gcov_var.start + gcov_var.offset; 449 gcov_unsigned_t *buffer = gcov_write_words (2); 450 451 buffer[0] = tag; 452 buffer[1] = 0; 453 454 return result; 455} 456 457/* Write a record length using POSITION, which was returned by 458 gcov_write_tag. The current file position is the end of the 459 record, and is restored before returning. Returns nonzero on 460 overflow. */ 461 462GCOV_LINKAGE void 463gcov_write_length (gcov_position_t position) 464{ 465 unsigned offset; 466 gcov_unsigned_t length; 467 gcov_unsigned_t *buffer; 468 469 gcc_assert (gcov_var.mode < 0); 470 gcc_assert (position + 2 <= gcov_var.start + gcov_var.offset); 471 gcc_assert (position >= gcov_var.start); 472 offset = position - gcov_var.start; 473 length = gcov_var.offset - offset - 2; 474 buffer = (gcov_unsigned_t *) &gcov_var.buffer[offset]; 475 buffer[1] = length; 476 if (gcov_var.offset >= GCOV_BLOCK_SIZE) 477 gcov_write_block (gcov_var.offset); 478} 479 480#else /* IN_LIBGCOV */ 481 482/* Write a tag TAG and length LENGTH. */ 483 484GCOV_LINKAGE void 485gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length) 486{ 487 gcov_unsigned_t *buffer = gcov_write_words (2); 488 489 buffer[0] = tag; 490 buffer[1] = length; 491} 492 493/* Write a summary structure to the gcov file. Return nonzero on 494 overflow. */ 495 496GCOV_LINKAGE void 497gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary) 498{ 499 unsigned ix, h_ix, bv_ix, h_cnt = 0; 500 const struct gcov_ctr_summary *csum; 501 unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; 502 503 /* Count number of non-zero histogram entries, and fill in a bit vector 504 of non-zero indices. The histogram is only currently computed for arc 505 counters. */ 506 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 507 histo_bitvector[bv_ix] = 0; 508 csum = &summary->ctrs[GCOV_COUNTER_ARCS]; 509 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) 510 { 511 if (csum->histogram[h_ix].num_counters > 0) 512 { 513 histo_bitvector[h_ix / 32] |= 1 << (h_ix % 32); 514 h_cnt++; 515 } 516 } 517 gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH (h_cnt)); 518 gcov_write_unsigned (summary->checksum); 519 for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) 520 { 521 gcov_write_unsigned (csum->num); 522 gcov_write_unsigned (csum->runs); 523 gcov_write_counter (csum->sum_all); 524 gcov_write_counter (csum->run_max); 525 gcov_write_counter (csum->sum_max); 526 if (ix != GCOV_COUNTER_ARCS) 527 { 528 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 529 gcov_write_unsigned (0); 530 continue; 531 } 532 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 533 gcov_write_unsigned (histo_bitvector[bv_ix]); 534 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) 535 { 536 if (!csum->histogram[h_ix].num_counters) 537 continue; 538 gcov_write_unsigned (csum->histogram[h_ix].num_counters); 539 gcov_write_counter (csum->histogram[h_ix].min_value); 540 gcov_write_counter (csum->histogram[h_ix].cum_value); 541 } 542 } 543} 544#endif /* IN_LIBGCOV */ 545 546#endif /*!IN_GCOV */ 547 548/* Return a pointer to read BYTES bytes from the gcov file. Returns 549 NULL on failure (read past EOF). */ 550 551static const gcov_unsigned_t * 552gcov_read_words (unsigned words) 553{ 554 const gcov_unsigned_t *result; 555 unsigned excess = gcov_var.length - gcov_var.offset; 556 557 gcc_assert (gcov_var.mode > 0); 558 if (excess < words) 559 { 560 gcov_var.start += gcov_var.offset; 561#if IN_LIBGCOV 562 if (excess) 563 { 564 gcc_assert (excess == 1); 565 memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4); 566 } 567#else 568 memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, excess * 4); 569#endif 570 gcov_var.offset = 0; 571 gcov_var.length = excess; 572#if IN_LIBGCOV 573 gcc_assert (!gcov_var.length || gcov_var.length == 1); 574 excess = GCOV_BLOCK_SIZE; 575#else 576 if (gcov_var.length + words > gcov_var.alloc) 577 gcov_allocate (gcov_var.length + words); 578 excess = gcov_var.alloc - gcov_var.length; 579#endif 580 excess = _GCOV_fread (gcov_var.buffer + gcov_var.length, 581 1, excess << 2, gcov_var.file) >> 2; 582 gcov_var.length += excess; 583 if (gcov_var.length < words) 584 { 585 gcov_var.overread += words - gcov_var.length; 586 gcov_var.length = 0; 587 return 0; 588 } 589 } 590 result = &gcov_var.buffer[gcov_var.offset]; 591 gcov_var.offset += words; 592 return result; 593} 594 595/* Read unsigned value from a coverage file. Sets error flag on file 596 error, overflow flag on overflow */ 597 598GCOV_LINKAGE gcov_unsigned_t 599gcov_read_unsigned (void) 600{ 601 gcov_unsigned_t value; 602 const gcov_unsigned_t *buffer = gcov_read_words (1); 603 604 if (!buffer) 605 return 0; 606 value = from_file (buffer[0]); 607 return value; 608} 609 610/* Read counter value from a coverage file. Sets error flag on file 611 error, overflow flag on overflow */ 612 613GCOV_LINKAGE gcov_type 614gcov_read_counter (void) 615{ 616 gcov_type value; 617 const gcov_unsigned_t *buffer = gcov_read_words (2); 618 619 if (!buffer) 620 return 0; 621 value = from_file (buffer[0]); 622 if (sizeof (value) > sizeof (gcov_unsigned_t)) 623 value |= ((gcov_type) from_file (buffer[1])) << 32; 624 else if (buffer[1]) 625 gcov_var.error = -1; 626 627 return value; 628} 629 630/* We need to expose the below function when compiling for gcov-tool. */ 631 632#if !IN_LIBGCOV || defined (IN_GCOV_TOOL) 633/* Read string from coverage file. Returns a pointer to a static 634 buffer, or NULL on empty string. You must copy the string before 635 calling another gcov function. */ 636 637GCOV_LINKAGE const char * 638gcov_read_string (void) 639{ 640 unsigned length = gcov_read_unsigned (); 641 642 if (!length) 643 return 0; 644 645 return (const char *) gcov_read_words (length); 646} 647#endif 648 649#ifdef __KERNEL__ 650static int 651k_popcountll (long long x) 652{ 653 int c = 0; 654 while (x) 655 { 656 c++; 657 x &= (x-1); 658 } 659 return c; 660} 661#endif 662 663GCOV_LINKAGE void 664gcov_read_summary (struct gcov_summary *summary) 665{ 666 unsigned ix, h_ix, bv_ix, h_cnt = 0; 667 struct gcov_ctr_summary *csum; 668 unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; 669 unsigned cur_bitvector; 670 671 summary->checksum = gcov_read_unsigned (); 672 for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) 673 { 674 csum->num = gcov_read_unsigned (); 675 csum->runs = gcov_read_unsigned (); 676 csum->sum_all = gcov_read_counter (); 677 csum->run_max = gcov_read_counter (); 678 csum->sum_max = gcov_read_counter (); 679 memset (csum->histogram, 0, 680 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); 681 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 682 { 683 histo_bitvector[bv_ix] = gcov_read_unsigned (); 684#if IN_LIBGCOV 685 /* When building libgcov we don't include system.h, which includes 686 hwint.h (where popcount_hwi is declared). However, libgcov.a 687 is built by the bootstrapped compiler and therefore the builtins 688 are always available. */ 689#ifndef __KERNEL__ 690 h_cnt += __builtin_popcount (histo_bitvector[bv_ix]); 691#else 692 h_cnt += k_popcountll (histo_bitvector[bv_ix]); 693#endif 694#else 695 h_cnt += popcount_hwi (histo_bitvector[bv_ix]); 696#endif 697 } 698 bv_ix = 0; 699 h_ix = 0; 700 cur_bitvector = 0; 701 while (h_cnt--) 702 { 703 /* Find the index corresponding to the next entry we will read in. 704 First find the next non-zero bitvector and re-initialize 705 the histogram index accordingly, then right shift and increment 706 the index until we find a set bit. */ 707 while (!cur_bitvector) 708 { 709 h_ix = bv_ix * 32; 710 gcc_assert (bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE); 711 cur_bitvector = histo_bitvector[bv_ix++]; 712 } 713 while (!(cur_bitvector & 0x1)) 714 { 715 h_ix++; 716 cur_bitvector >>= 1; 717 } 718 gcc_assert (h_ix < GCOV_HISTOGRAM_SIZE); 719 720 csum->histogram[h_ix].num_counters = gcov_read_unsigned (); 721 csum->histogram[h_ix].min_value = gcov_read_counter (); 722 csum->histogram[h_ix].cum_value = gcov_read_counter (); 723 /* Shift off the index we are done with and increment to the 724 corresponding next histogram entry. */ 725 cur_bitvector >>= 1; 726 h_ix++; 727 } 728 } 729} 730 731/* Read LENGTH words (unsigned type) from a zero profile fixup record with the 732 number of function flags saved in NUM_FNS. Returns the int flag array, which 733 should be deallocated by caller, or NULL on error. */ 734 735GCOV_LINKAGE int * 736gcov_read_comdat_zero_fixup (gcov_unsigned_t length, 737 gcov_unsigned_t *num_fns) 738{ 739#ifndef __KERNEL__ 740 unsigned ix, f_ix; 741 gcov_unsigned_t num = gcov_read_unsigned (); 742 /* The length consists of 1 word to hold the number of functions, 743 plus enough 32-bit words to hold 1 bit/function. */ 744 gcc_assert ((num + 31) / 32 + 1 == length); 745 int *zero_fixup_flags = (int *) xcalloc (num, sizeof (int)); 746 for (ix = 0; ix < length - 1; ix++) 747 { 748 gcov_unsigned_t bitvector = gcov_read_unsigned (); 749 f_ix = ix * 32; 750 while (bitvector) 751 { 752 if (bitvector & 0x1) 753 zero_fixup_flags[f_ix] = 1; 754 f_ix++; 755 bitvector >>= 1; 756 } 757 } 758 *num_fns = num; 759 return zero_fixup_flags; 760#else 761 return NULL; 762#endif 763} 764 765/* Read NUM_STRINGS strings (as an unsigned array) in STRING_ARRAY, and return 766 the number of words read. */ 767 768GCOV_LINKAGE gcov_unsigned_t 769gcov_read_string_array (char **string_array, gcov_unsigned_t num_strings) 770{ 771 gcov_unsigned_t i, j, len = 0; 772 773 for (j = 0; j < num_strings; j++) 774 { 775 gcov_unsigned_t string_len = gcov_read_unsigned (); 776 string_array[j] = 777 (char *) xmalloc (string_len * sizeof (gcov_unsigned_t)); 778 for (i = 0; i < string_len; i++) 779 ((gcov_unsigned_t *) string_array[j])[i] = gcov_read_unsigned (); 780 len += (string_len + 1); 781 } 782 return len; 783} 784 785/* Read LENGTH words (unsigned type) from a build info record with the number 786 of strings read saved in NUM_STRINGS. Returns the string array, which 787 should be deallocated by caller, or NULL on error. */ 788 789GCOV_LINKAGE char ** 790gcov_read_build_info (gcov_unsigned_t length, gcov_unsigned_t *num_strings) 791{ 792 gcov_unsigned_t num = gcov_read_unsigned (); 793 char **build_info_strings = (char **) 794 xmalloc (sizeof (char *) * num); 795 gcov_unsigned_t len = gcov_read_string_array (build_info_strings, 796 num); 797 if (len != length - 1) 798 return NULL; 799 *num_strings = num; 800 return build_info_strings; 801} 802 803#if (!IN_LIBGCOV && IN_GCOV != 1) || defined (IN_GCOV_TOOL) 804/* Read LEN words (unsigned type) and construct MOD_INFO. */ 805 806GCOV_LINKAGE void 807gcov_read_module_info (struct gcov_module_info *mod_info, 808 gcov_unsigned_t len) 809{ 810 gcov_unsigned_t src_filename_len, filename_len, i, num_strings; 811 mod_info->ident = gcov_read_unsigned (); 812 mod_info->is_primary = gcov_read_unsigned (); 813 mod_info->flags = gcov_read_unsigned (); 814 mod_info->lang = gcov_read_unsigned (); 815 mod_info->ggc_memory = gcov_read_unsigned (); 816 mod_info->num_quote_paths = gcov_read_unsigned (); 817 mod_info->num_bracket_paths = gcov_read_unsigned (); 818 mod_info->num_system_paths = gcov_read_unsigned (); 819 mod_info->num_cpp_defines = gcov_read_unsigned (); 820 mod_info->num_cpp_includes = gcov_read_unsigned (); 821 mod_info->num_cl_args = gcov_read_unsigned (); 822 len -= 11; 823 824 filename_len = gcov_read_unsigned (); 825 mod_info->da_filename = (char *) xmalloc (filename_len * 826 sizeof (gcov_unsigned_t)); 827 for (i = 0; i < filename_len; i++) 828 ((gcov_unsigned_t *) mod_info->da_filename)[i] = gcov_read_unsigned (); 829 len -= (filename_len + 1); 830 831 src_filename_len = gcov_read_unsigned (); 832 mod_info->source_filename = (char *) xmalloc (src_filename_len * 833 sizeof (gcov_unsigned_t)); 834 for (i = 0; i < src_filename_len; i++) 835 ((gcov_unsigned_t *) mod_info->source_filename)[i] = gcov_read_unsigned (); 836 len -= (src_filename_len + 1); 837 838 num_strings = mod_info->num_quote_paths + mod_info->num_bracket_paths 839 + mod_info->num_system_paths 840 + mod_info->num_cpp_defines + mod_info->num_cpp_includes 841 + mod_info->num_cl_args; 842 len -= gcov_read_string_array (mod_info->string_array, num_strings); 843 gcc_assert (!len); 844} 845#endif 846 847/* We need to expose the below function when compiling for gcov-tool. */ 848 849#if !IN_LIBGCOV || defined (IN_GCOV_TOOL) 850/* Reset to a known position. BASE should have been obtained from 851 gcov_position, LENGTH should be a record length. */ 852 853GCOV_LINKAGE void 854gcov_sync (gcov_position_t base, gcov_unsigned_t length) 855{ 856 gcc_assert (gcov_var.mode > 0); 857 base += length; 858 if (base - gcov_var.start <= gcov_var.length) 859 gcov_var.offset = base - gcov_var.start; 860 else 861 { 862 gcov_var.offset = gcov_var.length = 0; 863 _GCOV_fseek (gcov_var.file, base << 2, SEEK_SET); 864 gcov_var.start = _GCOV_ftell (gcov_var.file) >> 2; 865 } 866} 867#endif 868 869#if IN_LIBGCOV 870/* Move to a given position in a gcov file. */ 871 872GCOV_LINKAGE void 873gcov_seek (gcov_position_t base) 874{ 875 gcc_assert (gcov_var.mode < 0); 876 if (gcov_var.offset) 877 gcov_write_block (gcov_var.offset); 878 _GCOV_fseek (gcov_var.file, base << 2, SEEK_SET); 879 gcov_var.start = _GCOV_ftell (gcov_var.file) >> 2; 880} 881 882/* Truncate the gcov file at the current position. */ 883 884GCOV_LINKAGE void 885gcov_truncate (void) 886{ 887#ifdef __KERNEL__ 888 gcc_assert (0); 889#else 890 long offs; 891 int filenum; 892 gcc_assert (gcov_var.mode < 0); 893 if (gcov_var.offset) 894 gcov_write_block (gcov_var.offset); 895 offs = _GCOV_ftell (gcov_var.file); 896 filenum = fileno (gcov_var.file); 897 if (offs == -1 || filenum == -1 || _GCOV_ftruncate (filenum, offs)) 898 gcov_var.error = 1; 899#endif /* __KERNEL__ */ 900} 901#endif 902 903#if IN_GCOV > 0 904/* Return the modification time of the current gcov file. */ 905 906GCOV_LINKAGE time_t 907gcov_time (void) 908{ 909 struct stat status; 910 911 if (fstat (fileno (gcov_var.file), &status)) 912 return 0; 913 else 914 return status.st_mtime; 915} 916#endif /* IN_GCOV */ 917 918#if !IN_GCOV 919/* Determine the index into histogram for VALUE. */ 920 921#if IN_LIBGCOV 922static unsigned 923#else 924GCOV_LINKAGE unsigned 925#endif 926gcov_histo_index (gcov_type value) 927{ 928 gcov_type_unsigned v = (gcov_type_unsigned)value; 929 unsigned r = 0; 930 unsigned prev2bits = 0; 931 932 /* Find index into log2 scale histogram, where each of the log2 933 sized buckets is divided into 4 linear sub-buckets for better 934 focus in the higher buckets. */ 935 936 /* Find the place of the most-significant bit set. */ 937 if (v > 0) 938 { 939#if IN_LIBGCOV 940 /* When building libgcov we don't include system.h, which includes 941 hwint.h (where floor_log2 is declared). However, libgcov.a 942 is built by the bootstrapped compiler and therefore the builtins 943 are always available. */ 944 r = sizeof (long long) * __CHAR_BIT__ - 1 - __builtin_clzll (v); 945#else 946 /* We use floor_log2 from hwint.c, which takes a HOST_WIDE_INT 947 that is either 32 or 64 bits, and gcov_type_unsigned may be 64 bits. 948 Need to check for the case where gcov_type_unsigned is 64 bits 949 and HOST_WIDE_INT is 32 bits and handle it specially. */ 950#if HOST_BITS_PER_WIDEST_INT == HOST_BITS_PER_WIDE_INT 951 r = floor_log2 (v); 952#elif HOST_BITS_PER_WIDEST_INT == 2 * HOST_BITS_PER_WIDE_INT 953 HOST_WIDE_INT hwi_v = v >> HOST_BITS_PER_WIDE_INT; 954 if (hwi_v) 955 r = floor_log2 (hwi_v) + HOST_BITS_PER_WIDE_INT; 956 else 957 r = floor_log2 ((HOST_WIDE_INT)v); 958#else 959 gcc_unreachable (); 960#endif 961#endif 962 } 963 964 /* If at most the 2 least significant bits are set (value is 965 0 - 3) then that value is our index into the lowest set of 966 four buckets. */ 967 if (r < 2) 968 return (unsigned)value; 969 970 gcc_assert (r < 64); 971 972 /* Find the two next most significant bits to determine which 973 of the four linear sub-buckets to select. */ 974 prev2bits = (v >> (r - 2)) & 0x3; 975 /* Finally, compose the final bucket index from the log2 index and 976 the next 2 bits. The minimum r value at this point is 2 since we 977 returned above if r was 2 or more, so the minimum bucket at this 978 point is 4. */ 979 return (r - 1) * 4 + prev2bits; 980} 981 982/* Merge SRC_HISTO into TGT_HISTO. The counters are assumed to be in 983 the same relative order in both histograms, and are matched up 984 and merged in reverse order. Each counter is assigned an equal portion of 985 its entry's original cumulative counter value when computing the 986 new merged cum_value. */ 987 988static void gcov_histogram_merge (gcov_bucket_type *tgt_histo, 989 gcov_bucket_type *src_histo) 990{ 991 int src_i, tgt_i, tmp_i = 0; 992 unsigned src_num, tgt_num, merge_num; 993 gcov_type src_cum, tgt_cum, merge_src_cum, merge_tgt_cum, merge_cum; 994 gcov_type merge_min; 995 gcov_bucket_type tmp_histo[GCOV_HISTOGRAM_SIZE]; 996 int src_done = 0; 997 998 memset (tmp_histo, 0, sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); 999 1000 /* Assume that the counters are in the same relative order in both 1001 histograms. Walk the histograms from largest to smallest entry, 1002 matching up and combining counters in order. */ 1003 src_num = 0; 1004 src_cum = 0; 1005 src_i = GCOV_HISTOGRAM_SIZE - 1; 1006 for (tgt_i = GCOV_HISTOGRAM_SIZE - 1; tgt_i >= 0 && !src_done; tgt_i--) 1007 { 1008 tgt_num = tgt_histo[tgt_i].num_counters; 1009 tgt_cum = tgt_histo[tgt_i].cum_value; 1010 /* Keep going until all of the target histogram's counters at this 1011 position have been matched and merged with counters from the 1012 source histogram. */ 1013 while (tgt_num > 0 && !src_done) 1014 { 1015 /* If this is either the first time through this loop or we just 1016 exhausted the previous non-zero source histogram entry, look 1017 for the next non-zero source histogram entry. */ 1018 if (!src_num) 1019 { 1020 /* Locate the next non-zero entry. */ 1021 while (src_i >= 0 && !src_histo[src_i].num_counters) 1022 src_i--; 1023 /* If source histogram has fewer counters, then just copy over the 1024 remaining target counters and quit. */ 1025 if (src_i < 0) 1026 { 1027 tmp_histo[tgt_i].num_counters += tgt_num; 1028 tmp_histo[tgt_i].cum_value += tgt_cum; 1029 if (!tmp_histo[tgt_i].min_value || 1030 tgt_histo[tgt_i].min_value < tmp_histo[tgt_i].min_value) 1031 tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value; 1032 while (--tgt_i >= 0) 1033 { 1034 tmp_histo[tgt_i].num_counters 1035 += tgt_histo[tgt_i].num_counters; 1036 tmp_histo[tgt_i].cum_value += tgt_histo[tgt_i].cum_value; 1037 if (!tmp_histo[tgt_i].min_value || 1038 tgt_histo[tgt_i].min_value 1039 < tmp_histo[tgt_i].min_value) 1040 tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value; 1041 } 1042 1043 src_done = 1; 1044 break; 1045 } 1046 1047 src_num = src_histo[src_i].num_counters; 1048 src_cum = src_histo[src_i].cum_value; 1049 } 1050 1051 /* The number of counters to merge on this pass is the minimum 1052 of the remaining counters from the current target and source 1053 histogram entries. */ 1054 merge_num = tgt_num; 1055 if (src_num < merge_num) 1056 merge_num = src_num; 1057 1058 /* The merged min_value is the sum of the min_values from target 1059 and source. */ 1060 merge_min = tgt_histo[tgt_i].min_value + src_histo[src_i].min_value; 1061 1062 /* Compute the portion of source and target entries' cum_value 1063 that will be apportioned to the counters being merged. 1064 The total remaining cum_value from each entry is divided 1065 equally among the counters from that histogram entry if we 1066 are not merging all of them. */ 1067 merge_src_cum = src_cum; 1068 if (merge_num < src_num) 1069 merge_src_cum = merge_num * src_cum / src_num; 1070 merge_tgt_cum = tgt_cum; 1071 if (merge_num < tgt_num) 1072 merge_tgt_cum = merge_num * tgt_cum / tgt_num; 1073 /* The merged cum_value is the sum of the source and target 1074 components. */ 1075 merge_cum = merge_src_cum + merge_tgt_cum; 1076 1077 /* Update the remaining number of counters and cum_value left 1078 to be merged from this source and target entry. */ 1079 src_cum -= merge_src_cum; 1080 tgt_cum -= merge_tgt_cum; 1081 src_num -= merge_num; 1082 tgt_num -= merge_num; 1083 1084 /* The merged counters get placed in the new merged histogram 1085 at the entry for the merged min_value. */ 1086 tmp_i = gcov_histo_index (merge_min); 1087 gcc_assert (tmp_i < GCOV_HISTOGRAM_SIZE); 1088 tmp_histo[tmp_i].num_counters += merge_num; 1089 tmp_histo[tmp_i].cum_value += merge_cum; 1090 if (!tmp_histo[tmp_i].min_value || 1091 merge_min < tmp_histo[tmp_i].min_value) 1092 tmp_histo[tmp_i].min_value = merge_min; 1093 1094 /* Ensure the search for the next non-zero src_histo entry starts 1095 at the next smallest histogram bucket. */ 1096 if (!src_num) 1097 src_i--; 1098 } 1099 } 1100 1101 gcc_assert (tgt_i < 0); 1102 1103 /* In the case where there were more counters in the source histogram, 1104 accumulate the remaining unmerged cumulative counter values. Add 1105 those to the smallest non-zero target histogram entry. Otherwise, 1106 the total cumulative counter values in the histogram will be smaller 1107 than the sum_all stored in the summary, which will complicate 1108 computing the working set information from the histogram later on. */ 1109 if (src_num) 1110 src_i--; 1111 while (src_i >= 0) 1112 { 1113 src_cum += src_histo[src_i].cum_value; 1114 src_i--; 1115 } 1116 /* At this point, tmp_i should be the smallest non-zero entry in the 1117 tmp_histo. */ 1118 gcc_assert (tmp_i >= 0 && tmp_i < GCOV_HISTOGRAM_SIZE 1119 && tmp_histo[tmp_i].num_counters > 0); 1120 tmp_histo[tmp_i].cum_value += src_cum; 1121 1122 /* Finally, copy the merged histogram into tgt_histo. */ 1123 memcpy (tgt_histo, tmp_histo, 1124 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); 1125} 1126#endif /* !IN_GCOV */ 1127 1128/* This is used by gcov-dump (IN_GCOV == -1) and in the compiler 1129 (!IN_GCOV && !IN_LIBGCOV). */ 1130#if IN_GCOV <= 0 && !IN_LIBGCOV 1131/* Compute the working set information from the counter histogram in 1132 the profile summary. This is an array of information corresponding to a 1133 range of percentages of the total execution count (sum_all), and includes 1134 the number of counters required to cover that working set percentage and 1135 the minimum counter value in that working set. */ 1136 1137GCOV_LINKAGE void 1138compute_working_sets (const struct gcov_ctr_summary *summary, 1139 gcov_working_set_t *gcov_working_sets) 1140{ 1141 gcov_type working_set_cum_values[NUM_GCOV_WORKING_SETS]; 1142 gcov_type ws_cum_hotness_incr; 1143 gcov_type cum, tmp_cum; 1144 const gcov_bucket_type *histo_bucket; 1145 unsigned ws_ix, c_num, count; 1146 int h_ix; 1147 1148 /* Compute the amount of sum_all that the cumulative hotness grows 1149 by in each successive working set entry, which depends on the 1150 number of working set entries. */ 1151 ws_cum_hotness_incr = summary->sum_all / NUM_GCOV_WORKING_SETS; 1152 1153 /* Next fill in an array of the cumulative hotness values corresponding 1154 to each working set summary entry we are going to compute below. 1155 Skip 0% statistics, which can be extrapolated from the 1156 rest of the summary data. */ 1157 cum = ws_cum_hotness_incr; 1158 for (ws_ix = 0; ws_ix < NUM_GCOV_WORKING_SETS; 1159 ws_ix++, cum += ws_cum_hotness_incr) 1160 working_set_cum_values[ws_ix] = cum; 1161 /* The last summary entry is reserved for (roughly) 99.9% of the 1162 working set. Divide by 1024 so it becomes a shift, which gives 1163 almost exactly 99.9%. */ 1164 working_set_cum_values[NUM_GCOV_WORKING_SETS-1] 1165 = summary->sum_all - summary->sum_all/1024; 1166 1167 /* Next, walk through the histogram in decending order of hotness 1168 and compute the statistics for the working set summary array. 1169 As histogram entries are accumulated, we check to see which 1170 working set entries have had their expected cum_value reached 1171 and fill them in, walking the working set entries in increasing 1172 size of cum_value. */ 1173 ws_ix = 0; /* The current entry into the working set array. */ 1174 cum = 0; /* The current accumulated counter sum. */ 1175 count = 0; /* The current accumulated count of block counters. */ 1176 for (h_ix = GCOV_HISTOGRAM_SIZE - 1; 1177 h_ix >= 0 && ws_ix < NUM_GCOV_WORKING_SETS; h_ix--) 1178 { 1179 histo_bucket = &summary->histogram[h_ix]; 1180 1181 /* If we haven't reached the required cumulative counter value for 1182 the current working set percentage, simply accumulate this histogram 1183 entry into the running sums and continue to the next histogram 1184 entry. */ 1185 if (cum + histo_bucket->cum_value < working_set_cum_values[ws_ix]) 1186 { 1187 cum += histo_bucket->cum_value; 1188 count += histo_bucket->num_counters; 1189 continue; 1190 } 1191 1192 /* If adding the current histogram entry's cumulative counter value 1193 causes us to exceed the current working set size, then estimate 1194 how many of this histogram entry's counter values are required to 1195 reach the working set size, and fill in working set entries 1196 as we reach their expected cumulative value. */ 1197 for (c_num = 0, tmp_cum = cum; 1198 c_num < histo_bucket->num_counters && ws_ix < NUM_GCOV_WORKING_SETS; 1199 c_num++) 1200 { 1201 count++; 1202 /* If we haven't reached the last histogram entry counter, add 1203 in the minimum value again. This will underestimate the 1204 cumulative sum so far, because many of the counter values in this 1205 entry may have been larger than the minimum. We could add in the 1206 average value every time, but that would require an expensive 1207 divide operation. */ 1208 if (c_num + 1 < histo_bucket->num_counters) 1209 tmp_cum += histo_bucket->min_value; 1210 /* If we have reached the last histogram entry counter, then add 1211 in the entire cumulative value. */ 1212 else 1213 tmp_cum = cum + histo_bucket->cum_value; 1214 1215 /* Next walk through successive working set entries and fill in 1216 the statistics for any whose size we have reached by accumulating 1217 this histogram counter. */ 1218 while (ws_ix < NUM_GCOV_WORKING_SETS 1219 && tmp_cum >= working_set_cum_values[ws_ix]) 1220 { 1221 gcov_working_sets[ws_ix].num_counters = count; 1222 gcov_working_sets[ws_ix].min_counter 1223 = histo_bucket->min_value; 1224 ws_ix++; 1225 } 1226 } 1227 /* Finally, update the running cumulative value since we were 1228 using a temporary above. */ 1229 cum += histo_bucket->cum_value; 1230 } 1231 gcc_assert (ws_ix == NUM_GCOV_WORKING_SETS); 1232} 1233#endif /* IN_GCOV <= 0 && !IN_LIBGCOV */ 1234