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 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 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 123GCOV_LINKAGE int 124#if IN_LIBGCOV 125gcov_open (const char *name) 126#else 127gcov_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 gcc_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 228GCOV_LINKAGE int 229gcov_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 255GCOV_LINKAGE int 256gcov_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 272static void 273gcov_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 290static void 291gcov_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 302static gcov_unsigned_t * 303gcov_write_words (unsigned words) 304{ 305 gcov_unsigned_t *result; 306 307 gcc_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 gcc_assert (gcov_var.offset == 1); 315 memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4); 316 } 317 } 318#else 319 if (gcov_var.offset + words > gcov_var.alloc) 320 gcov_allocate (gcov_var.offset + words); 321#endif 322 result = &gcov_var.buffer[gcov_var.offset]; 323 gcov_var.offset += words; 324 325 return result; 326} 327 328/* Write unsigned VALUE to coverage file. Sets error flag 329 appropriately. */ 330 331GCOV_LINKAGE void 332gcov_write_unsigned (gcov_unsigned_t value) 333{ 334 gcov_unsigned_t *buffer = gcov_write_words (1); 335 336 buffer[0] = value; 337} 338 339/* Write counter VALUE to coverage file. Sets error flag 340 appropriately. */ 341 342#if IN_LIBGCOV 343GCOV_LINKAGE void 344gcov_write_counter (gcov_type value) 345{ 346 gcov_unsigned_t *buffer = gcov_write_words (2); 347 348 buffer[0] = (gcov_unsigned_t) value; 349 if (sizeof (value) > sizeof (gcov_unsigned_t)) 350 buffer[1] = (gcov_unsigned_t) (value >> 32); 351 else 352 buffer[1] = 0; 353} 354#endif /* IN_LIBGCOV */ 355 356#if !IN_LIBGCOV 357/* Write STRING to coverage file. Sets error flag on file 358 error, overflow flag on overflow */ 359 360GCOV_LINKAGE void 361gcov_write_string (const char *string) 362{ 363 unsigned length = 0; 364 unsigned alloc = 0; 365 gcov_unsigned_t *buffer; 366 367 if (string) 368 { 369 length = strlen (string); 370 alloc = (length + 4) >> 2; 371 } 372 373 buffer = gcov_write_words (1 + alloc); 374 375 buffer[0] = alloc; 376 buffer[alloc] = 0; 377 memcpy (&buffer[1], string, length); 378} 379#endif 380 381#if !IN_LIBGCOV 382/* Write a tag TAG and reserve space for the record length. Return a 383 value to be used for gcov_write_length. */ 384 385GCOV_LINKAGE gcov_position_t 386gcov_write_tag (gcov_unsigned_t tag) 387{ 388 gcov_position_t result = gcov_var.start + gcov_var.offset; 389 gcov_unsigned_t *buffer = gcov_write_words (2); 390 391 buffer[0] = tag; 392 buffer[1] = 0; 393 394 return result; 395} 396 397/* Write a record length using POSITION, which was returned by 398 gcov_write_tag. The current file position is the end of the 399 record, and is restored before returning. Returns nonzero on 400 overflow. */ 401 402GCOV_LINKAGE void 403gcov_write_length (gcov_position_t position) 404{ 405 unsigned offset; 406 gcov_unsigned_t length; 407 gcov_unsigned_t *buffer; 408 409 gcc_assert (gcov_var.mode < 0); 410 gcc_assert (position + 2 <= gcov_var.start + gcov_var.offset); 411 gcc_assert (position >= gcov_var.start); 412 offset = position - gcov_var.start; 413 length = gcov_var.offset - offset - 2; 414 buffer = (gcov_unsigned_t *) &gcov_var.buffer[offset]; 415 buffer[1] = length; 416 if (gcov_var.offset >= GCOV_BLOCK_SIZE) 417 gcov_write_block (gcov_var.offset); 418} 419 420#else /* IN_LIBGCOV */ 421 422/* Write a tag TAG and length LENGTH. */ 423 424GCOV_LINKAGE void 425gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length) 426{ 427 gcov_unsigned_t *buffer = gcov_write_words (2); 428 429 buffer[0] = tag; 430 buffer[1] = length; 431} 432 433/* Write a summary structure to the gcov file. Return nonzero on 434 overflow. */ 435 436GCOV_LINKAGE void 437gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary) 438{ 439 unsigned ix, h_ix, bv_ix, h_cnt = 0; 440 const struct gcov_ctr_summary *csum; 441 unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; 442 443 /* Count number of non-zero histogram entries, and fill in a bit vector 444 of non-zero indices. The histogram is only currently computed for arc 445 counters. */ 446 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 447 histo_bitvector[bv_ix] = 0; 448 csum = &summary->ctrs[GCOV_COUNTER_ARCS]; 449 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) 450 { 451 if (csum->histogram[h_ix].num_counters > 0) 452 { 453 histo_bitvector[h_ix / 32] |= 1 << (h_ix % 32); 454 h_cnt++; 455 } 456 } 457 gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH (h_cnt)); 458 gcov_write_unsigned (summary->checksum); 459 for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) 460 { 461 gcov_write_unsigned (csum->num); 462 gcov_write_unsigned (csum->runs); 463 gcov_write_counter (csum->sum_all); 464 gcov_write_counter (csum->run_max); 465 gcov_write_counter (csum->sum_max); 466 if (ix != GCOV_COUNTER_ARCS) 467 { 468 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 469 gcov_write_unsigned (0); 470 continue; 471 } 472 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 473 gcov_write_unsigned (histo_bitvector[bv_ix]); 474 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) 475 { 476 if (!csum->histogram[h_ix].num_counters) 477 continue; 478 gcov_write_unsigned (csum->histogram[h_ix].num_counters); 479 gcov_write_counter (csum->histogram[h_ix].min_value); 480 gcov_write_counter (csum->histogram[h_ix].cum_value); 481 } 482 } 483} 484#endif /* IN_LIBGCOV */ 485 486#endif /*!IN_GCOV */ 487 488/* Return a pointer to read BYTES bytes from the gcov file. Returns 489 NULL on failure (read past EOF). */ 490 491static const gcov_unsigned_t * 492gcov_read_words (unsigned words) 493{ 494 const gcov_unsigned_t *result; 495 unsigned excess = gcov_var.length - gcov_var.offset; 496 497 gcc_assert (gcov_var.mode > 0); 498 if (excess < words) 499 { 500 gcov_var.start += gcov_var.offset; 501#if IN_LIBGCOV 502 if (excess) 503 { 504 gcc_assert (excess == 1); 505 memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4); 506 } 507#else 508 memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, excess * 4); 509#endif 510 gcov_var.offset = 0; 511 gcov_var.length = excess; 512#if IN_LIBGCOV 513 gcc_assert (!gcov_var.length || gcov_var.length == 1); 514 excess = GCOV_BLOCK_SIZE; 515#else 516 if (gcov_var.length + words > gcov_var.alloc) 517 gcov_allocate (gcov_var.length + words); 518 excess = gcov_var.alloc - gcov_var.length; 519#endif 520 excess = fread (gcov_var.buffer + gcov_var.length, 521 1, excess << 2, gcov_var.file) >> 2; 522 gcov_var.length += excess; 523 if (gcov_var.length < words) 524 { 525 gcov_var.overread += words - gcov_var.length; 526 gcov_var.length = 0; 527 return 0; 528 } 529 } 530 result = &gcov_var.buffer[gcov_var.offset]; 531 gcov_var.offset += words; 532 return result; 533} 534 535/* Read unsigned value from a coverage file. Sets error flag on file 536 error, overflow flag on overflow */ 537 538GCOV_LINKAGE gcov_unsigned_t 539gcov_read_unsigned (void) 540{ 541 gcov_unsigned_t value; 542 const gcov_unsigned_t *buffer = gcov_read_words (1); 543 544 if (!buffer) 545 return 0; 546 value = from_file (buffer[0]); 547 return value; 548} 549 550/* Read counter value from a coverage file. Sets error flag on file 551 error, overflow flag on overflow */ 552 553GCOV_LINKAGE gcov_type 554gcov_read_counter (void) 555{ 556 gcov_type value; 557 const gcov_unsigned_t *buffer = gcov_read_words (2); 558 559 if (!buffer) 560 return 0; 561 value = from_file (buffer[0]); 562 if (sizeof (value) > sizeof (gcov_unsigned_t)) 563 value |= ((gcov_type) from_file (buffer[1])) << 32; 564 else if (buffer[1]) 565 gcov_var.error = -1; 566 567 return value; 568} 569 570/* We need to expose the below function when compiling for gcov-tool. */ 571 572#if !IN_LIBGCOV || defined (IN_GCOV_TOOL) 573/* Read string from coverage file. Returns a pointer to a static 574 buffer, or NULL on empty string. You must copy the string before 575 calling another gcov function. */ 576 577GCOV_LINKAGE const char * 578gcov_read_string (void) 579{ 580 unsigned length = gcov_read_unsigned (); 581 582 if (!length) 583 return 0; 584 585 return (const char *) gcov_read_words (length); 586} 587#endif 588 589GCOV_LINKAGE void 590gcov_read_summary (struct gcov_summary *summary) 591{ 592 unsigned ix, h_ix, bv_ix, h_cnt = 0; 593 struct gcov_ctr_summary *csum; 594 unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; 595 unsigned cur_bitvector; 596 597 summary->checksum = gcov_read_unsigned (); 598 for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) 599 { 600 csum->num = gcov_read_unsigned (); 601 csum->runs = gcov_read_unsigned (); 602 csum->sum_all = gcov_read_counter (); 603 csum->run_max = gcov_read_counter (); 604 csum->sum_max = gcov_read_counter (); 605 memset (csum->histogram, 0, 606 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); 607 for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) 608 { 609 histo_bitvector[bv_ix] = gcov_read_unsigned (); 610#if IN_LIBGCOV 611 /* When building libgcov we don't include system.h, which includes 612 hwint.h (where popcount_hwi is declared). However, libgcov.a 613 is built by the bootstrapped compiler and therefore the builtins 614 are always available. */ 615 h_cnt += __builtin_popcount (histo_bitvector[bv_ix]); 616#else 617 h_cnt += popcount_hwi (histo_bitvector[bv_ix]); 618#endif 619 } 620 bv_ix = 0; 621 h_ix = 0; 622 cur_bitvector = 0; 623 while (h_cnt--) 624 { 625 /* Find the index corresponding to the next entry we will read in. 626 First find the next non-zero bitvector and re-initialize 627 the histogram index accordingly, then right shift and increment 628 the index until we find a set bit. */ 629 while (!cur_bitvector) 630 { 631 h_ix = bv_ix * 32; 632 gcc_assert (bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE); 633 cur_bitvector = histo_bitvector[bv_ix++]; 634 } 635 while (!(cur_bitvector & 0x1)) 636 { 637 h_ix++; 638 cur_bitvector >>= 1; 639 } 640 gcc_assert (h_ix < GCOV_HISTOGRAM_SIZE); 641 642 csum->histogram[h_ix].num_counters = gcov_read_unsigned (); 643 csum->histogram[h_ix].min_value = gcov_read_counter (); 644 csum->histogram[h_ix].cum_value = gcov_read_counter (); 645 /* Shift off the index we are done with and increment to the 646 corresponding next histogram entry. */ 647 cur_bitvector >>= 1; 648 h_ix++; 649 } 650 } 651} 652 653#if (!IN_LIBGCOV && IN_GCOV != 1) || defined (IN_GCOV_TOOL) 654/* Read LEN words (unsigned type) and construct MOD_INFO. */ 655 656GCOV_LINKAGE void 657gcov_read_module_info (struct gcov_module_info *mod_info, 658 gcov_unsigned_t len) 659{ 660 gcov_unsigned_t src_filename_len, filename_len, i, j, num_strings; 661 mod_info->ident = gcov_read_unsigned (); 662 mod_info->is_primary = gcov_read_unsigned (); 663 mod_info->flags = gcov_read_unsigned (); 664 mod_info->lang = gcov_read_unsigned (); 665 mod_info->ggc_memory = gcov_read_unsigned (); 666 mod_info->num_quote_paths = gcov_read_unsigned (); 667 mod_info->num_bracket_paths = gcov_read_unsigned (); 668 mod_info->num_system_paths = gcov_read_unsigned (); 669 mod_info->num_cpp_defines = gcov_read_unsigned (); 670 mod_info->num_cpp_includes = gcov_read_unsigned (); 671 mod_info->num_cl_args = gcov_read_unsigned (); 672 len -= 11; 673 674 filename_len = gcov_read_unsigned (); 675 mod_info->da_filename = (char *) xmalloc (filename_len * 676 sizeof (gcov_unsigned_t)); 677 for (i = 0; i < filename_len; i++) 678 ((gcov_unsigned_t *) mod_info->da_filename)[i] = gcov_read_unsigned (); 679 len -= (filename_len + 1); 680 681 src_filename_len = gcov_read_unsigned (); 682 mod_info->source_filename = (char *) xmalloc (src_filename_len * 683 sizeof (gcov_unsigned_t)); 684 for (i = 0; i < src_filename_len; i++) 685 ((gcov_unsigned_t *) mod_info->source_filename)[i] = gcov_read_unsigned (); 686 len -= (src_filename_len + 1); 687 688 num_strings = mod_info->num_quote_paths + mod_info->num_bracket_paths 689 + mod_info->num_system_paths 690 + mod_info->num_cpp_defines + mod_info->num_cpp_includes 691 + mod_info->num_cl_args; 692 for (j = 0; j < num_strings; j++) 693 { 694 gcov_unsigned_t string_len = gcov_read_unsigned (); 695 mod_info->string_array[j] = 696 (char *) xmalloc (string_len * sizeof (gcov_unsigned_t)); 697 for (i = 0; i < string_len; i++) 698 ((gcov_unsigned_t *) mod_info->string_array[j])[i] = 699 gcov_read_unsigned (); 700 len -= (string_len + 1); 701 } 702 gcc_assert (!len); 703} 704#endif 705 706/* We need to expose the below function when compiling for gcov-tool. */ 707 708#if !IN_LIBGCOV || defined (IN_GCOV_TOOL) 709/* Reset to a known position. BASE should have been obtained from 710 gcov_position, LENGTH should be a record length. */ 711 712GCOV_LINKAGE void 713gcov_sync (gcov_position_t base, gcov_unsigned_t length) 714{ 715 gcc_assert (gcov_var.mode > 0); 716 base += length; 717 if (base - gcov_var.start <= gcov_var.length) 718 gcov_var.offset = base - gcov_var.start; 719 else 720 { 721 gcov_var.offset = gcov_var.length = 0; 722 fseek (gcov_var.file, base << 2, SEEK_SET); 723 gcov_var.start = ftell (gcov_var.file) >> 2; 724 } 725} 726#endif 727 728#if IN_LIBGCOV 729/* Move to a given position in a gcov file. */ 730 731GCOV_LINKAGE void 732gcov_seek (gcov_position_t base) 733{ 734 gcc_assert (gcov_var.mode < 0); 735 if (gcov_var.offset) 736 gcov_write_block (gcov_var.offset); 737 fseek (gcov_var.file, base << 2, SEEK_SET); 738 gcov_var.start = ftell (gcov_var.file) >> 2; 739} 740 741/* Truncate the gcov file at the current position. */ 742 743GCOV_LINKAGE void 744gcov_truncate (void) 745{ 746 long offs; 747 int filenum; 748 gcc_assert (gcov_var.mode < 0); 749 if (gcov_var.offset) 750 gcov_write_block (gcov_var.offset); 751 offs = ftell (gcov_var.file); 752 filenum = fileno (gcov_var.file); 753 if (offs == -1 || filenum == -1 || ftruncate (filenum, offs)) 754 gcov_var.error = 1; 755} 756#endif 757 758#if IN_GCOV > 0 759/* Return the modification time of the current gcov file. */ 760 761GCOV_LINKAGE time_t 762gcov_time (void) 763{ 764 struct stat status; 765 766 if (fstat (fileno (gcov_var.file), &status)) 767 return 0; 768 else 769 return status.st_mtime; 770} 771#endif /* IN_GCOV */ 772 773#if !IN_GCOV 774/* Determine the index into histogram for VALUE. */ 775 776#if IN_LIBGCOV 777static unsigned 778#else 779GCOV_LINKAGE unsigned 780#endif 781gcov_histo_index (gcov_type value) 782{ 783 gcov_type_unsigned v = (gcov_type_unsigned)value; 784 unsigned r = 0; 785 unsigned prev2bits = 0; 786 787 /* Find index into log2 scale histogram, where each of the log2 788 sized buckets is divided into 4 linear sub-buckets for better 789 focus in the higher buckets. */ 790 791 /* Find the place of the most-significant bit set. */ 792 if (v > 0) 793 { 794#if IN_LIBGCOV 795 /* When building libgcov we don't include system.h, which includes 796 hwint.h (where floor_log2 is declared). However, libgcov.a 797 is built by the bootstrapped compiler and therefore the builtins 798 are always available. */ 799 r = sizeof (long long) * __CHAR_BIT__ - 1 - __builtin_clzll (v); 800#else 801 /* We use floor_log2 from hwint.c, which takes a HOST_WIDE_INT 802 that is either 32 or 64 bits, and gcov_type_unsigned may be 64 bits. 803 Need to check for the case where gcov_type_unsigned is 64 bits 804 and HOST_WIDE_INT is 32 bits and handle it specially. */ 805#if HOST_BITS_PER_WIDEST_INT == HOST_BITS_PER_WIDE_INT 806 r = floor_log2 (v); 807#elif HOST_BITS_PER_WIDEST_INT == 2 * HOST_BITS_PER_WIDE_INT 808 HOST_WIDE_INT hwi_v = v >> HOST_BITS_PER_WIDE_INT; 809 if (hwi_v) 810 r = floor_log2 (hwi_v) + HOST_BITS_PER_WIDE_INT; 811 else 812 r = floor_log2 ((HOST_WIDE_INT)v); 813#else 814 gcc_unreachable (); 815#endif 816#endif 817 } 818 819 /* If at most the 2 least significant bits are set (value is 820 0 - 3) then that value is our index into the lowest set of 821 four buckets. */ 822 if (r < 2) 823 return (unsigned)value; 824 825 gcc_assert (r < 64); 826 827 /* Find the two next most significant bits to determine which 828 of the four linear sub-buckets to select. */ 829 prev2bits = (v >> (r - 2)) & 0x3; 830 /* Finally, compose the final bucket index from the log2 index and 831 the next 2 bits. The minimum r value at this point is 2 since we 832 returned above if r was 2 or more, so the minimum bucket at this 833 point is 4. */ 834 return (r - 1) * 4 + prev2bits; 835} 836 837/* Merge SRC_HISTO into TGT_HISTO. The counters are assumed to be in 838 the same relative order in both histograms, and are matched up 839 and merged in reverse order. Each counter is assigned an equal portion of 840 its entry's original cumulative counter value when computing the 841 new merged cum_value. */ 842 843static void gcov_histogram_merge (gcov_bucket_type *tgt_histo, 844 gcov_bucket_type *src_histo) 845{ 846 int src_i, tgt_i, tmp_i = 0; 847 unsigned src_num, tgt_num, merge_num; 848 gcov_type src_cum, tgt_cum, merge_src_cum, merge_tgt_cum, merge_cum; 849 gcov_type merge_min; 850 gcov_bucket_type tmp_histo[GCOV_HISTOGRAM_SIZE]; 851 int src_done = 0; 852 853 memset (tmp_histo, 0, sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); 854 855 /* Assume that the counters are in the same relative order in both 856 histograms. Walk the histograms from largest to smallest entry, 857 matching up and combining counters in order. */ 858 src_num = 0; 859 src_cum = 0; 860 src_i = GCOV_HISTOGRAM_SIZE - 1; 861 for (tgt_i = GCOV_HISTOGRAM_SIZE - 1; tgt_i >= 0 && !src_done; tgt_i--) 862 { 863 tgt_num = tgt_histo[tgt_i].num_counters; 864 tgt_cum = tgt_histo[tgt_i].cum_value; 865 /* Keep going until all of the target histogram's counters at this 866 position have been matched and merged with counters from the 867 source histogram. */ 868 while (tgt_num > 0 && !src_done) 869 { 870 /* If this is either the first time through this loop or we just 871 exhausted the previous non-zero source histogram entry, look 872 for the next non-zero source histogram entry. */ 873 if (!src_num) 874 { 875 /* Locate the next non-zero entry. */ 876 while (src_i >= 0 && !src_histo[src_i].num_counters) 877 src_i--; 878 /* If source histogram has fewer counters, then just copy over the 879 remaining target counters and quit. */ 880 if (src_i < 0) 881 { 882 tmp_histo[tgt_i].num_counters += tgt_num; 883 tmp_histo[tgt_i].cum_value += tgt_cum; 884 if (!tmp_histo[tgt_i].min_value || 885 tgt_histo[tgt_i].min_value < tmp_histo[tgt_i].min_value) 886 tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value; 887 while (--tgt_i >= 0) 888 { 889 tmp_histo[tgt_i].num_counters 890 += tgt_histo[tgt_i].num_counters; 891 tmp_histo[tgt_i].cum_value += tgt_histo[tgt_i].cum_value; 892 if (!tmp_histo[tgt_i].min_value || 893 tgt_histo[tgt_i].min_value 894 < tmp_histo[tgt_i].min_value) 895 tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value; 896 } 897 898 src_done = 1; 899 break; 900 } 901 902 src_num = src_histo[src_i].num_counters; 903 src_cum = src_histo[src_i].cum_value; 904 } 905 906 /* The number of counters to merge on this pass is the minimum 907 of the remaining counters from the current target and source 908 histogram entries. */ 909 merge_num = tgt_num; 910 if (src_num < merge_num) 911 merge_num = src_num; 912 913 /* The merged min_value is the sum of the min_values from target 914 and source. */ 915 merge_min = tgt_histo[tgt_i].min_value + src_histo[src_i].min_value; 916 917 /* Compute the portion of source and target entries' cum_value 918 that will be apportioned to the counters being merged. 919 The total remaining cum_value from each entry is divided 920 equally among the counters from that histogram entry if we 921 are not merging all of them. */ 922 merge_src_cum = src_cum; 923 if (merge_num < src_num) 924 merge_src_cum = merge_num * src_cum / src_num; 925 merge_tgt_cum = tgt_cum; 926 if (merge_num < tgt_num) 927 merge_tgt_cum = merge_num * tgt_cum / tgt_num; 928 /* The merged cum_value is the sum of the source and target 929 components. */ 930 merge_cum = merge_src_cum + merge_tgt_cum; 931 932 /* Update the remaining number of counters and cum_value left 933 to be merged from this source and target entry. */ 934 src_cum -= merge_src_cum; 935 tgt_cum -= merge_tgt_cum; 936 src_num -= merge_num; 937 tgt_num -= merge_num; 938 939 /* The merged counters get placed in the new merged histogram 940 at the entry for the merged min_value. */ 941 tmp_i = gcov_histo_index (merge_min); 942 gcc_assert (tmp_i < GCOV_HISTOGRAM_SIZE); 943 tmp_histo[tmp_i].num_counters += merge_num; 944 tmp_histo[tmp_i].cum_value += merge_cum; 945 if (!tmp_histo[tmp_i].min_value || 946 merge_min < tmp_histo[tmp_i].min_value) 947 tmp_histo[tmp_i].min_value = merge_min; 948 949 /* Ensure the search for the next non-zero src_histo entry starts 950 at the next smallest histogram bucket. */ 951 if (!src_num) 952 src_i--; 953 } 954 } 955 956 gcc_assert (tgt_i < 0); 957 958 /* In the case where there were more counters in the source histogram, 959 accumulate the remaining unmerged cumulative counter values. Add 960 those to the smallest non-zero target histogram entry. Otherwise, 961 the total cumulative counter values in the histogram will be smaller 962 than the sum_all stored in the summary, which will complicate 963 computing the working set information from the histogram later on. */ 964 if (src_num) 965 src_i--; 966 while (src_i >= 0) 967 { 968 src_cum += src_histo[src_i].cum_value; 969 src_i--; 970 } 971 /* At this point, tmp_i should be the smallest non-zero entry in the 972 tmp_histo. */ 973 gcc_assert (tmp_i >= 0 && tmp_i < GCOV_HISTOGRAM_SIZE 974 && tmp_histo[tmp_i].num_counters > 0); 975 tmp_histo[tmp_i].cum_value += src_cum; 976 977 /* Finally, copy the merged histogram into tgt_histo. */ 978 memcpy (tgt_histo, tmp_histo, 979 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); 980} 981#endif /* !IN_GCOV */ 982 983/* This is used by gcov-dump (IN_GCOV == -1) and in the compiler 984 (!IN_GCOV && !IN_LIBGCOV). */ 985#if IN_GCOV <= 0 && !IN_LIBGCOV 986/* Compute the working set information from the counter histogram in 987 the profile summary. This is an array of information corresponding to a 988 range of percentages of the total execution count (sum_all), and includes 989 the number of counters required to cover that working set percentage and 990 the minimum counter value in that working set. */ 991 992GCOV_LINKAGE void 993compute_working_sets (const struct gcov_ctr_summary *summary, 994 gcov_working_set_t *gcov_working_sets) 995{ 996 gcov_type working_set_cum_values[NUM_GCOV_WORKING_SETS]; 997 gcov_type ws_cum_hotness_incr; 998 gcov_type cum, tmp_cum; 999 const gcov_bucket_type *histo_bucket; 1000 unsigned ws_ix, c_num, count; 1001 int h_ix; 1002 1003 /* Compute the amount of sum_all that the cumulative hotness grows 1004 by in each successive working set entry, which depends on the 1005 number of working set entries. */ 1006 ws_cum_hotness_incr = summary->sum_all / NUM_GCOV_WORKING_SETS; 1007 1008 /* Next fill in an array of the cumulative hotness values corresponding 1009 to each working set summary entry we are going to compute below. 1010 Skip 0% statistics, which can be extrapolated from the 1011 rest of the summary data. */ 1012 cum = ws_cum_hotness_incr; 1013 for (ws_ix = 0; ws_ix < NUM_GCOV_WORKING_SETS; 1014 ws_ix++, cum += ws_cum_hotness_incr) 1015 working_set_cum_values[ws_ix] = cum; 1016 /* The last summary entry is reserved for (roughly) 99.9% of the 1017 working set. Divide by 1024 so it becomes a shift, which gives 1018 almost exactly 99.9%. */ 1019 working_set_cum_values[NUM_GCOV_WORKING_SETS-1] 1020 = summary->sum_all - summary->sum_all/1024; 1021 1022 /* Next, walk through the histogram in decending order of hotness 1023 and compute the statistics for the working set summary array. 1024 As histogram entries are accumulated, we check to see which 1025 working set entries have had their expected cum_value reached 1026 and fill them in, walking the working set entries in increasing 1027 size of cum_value. */ 1028 ws_ix = 0; /* The current entry into the working set array. */ 1029 cum = 0; /* The current accumulated counter sum. */ 1030 count = 0; /* The current accumulated count of block counters. */ 1031 for (h_ix = GCOV_HISTOGRAM_SIZE - 1; 1032 h_ix >= 0 && ws_ix < NUM_GCOV_WORKING_SETS; h_ix--) 1033 { 1034 histo_bucket = &summary->histogram[h_ix]; 1035 1036 /* If we haven't reached the required cumulative counter value for 1037 the current working set percentage, simply accumulate this histogram 1038 entry into the running sums and continue to the next histogram 1039 entry. */ 1040 if (cum + histo_bucket->cum_value < working_set_cum_values[ws_ix]) 1041 { 1042 cum += histo_bucket->cum_value; 1043 count += histo_bucket->num_counters; 1044 continue; 1045 } 1046 1047 /* If adding the current histogram entry's cumulative counter value 1048 causes us to exceed the current working set size, then estimate 1049 how many of this histogram entry's counter values are required to 1050 reach the working set size, and fill in working set entries 1051 as we reach their expected cumulative value. */ 1052 for (c_num = 0, tmp_cum = cum; 1053 c_num < histo_bucket->num_counters && ws_ix < NUM_GCOV_WORKING_SETS; 1054 c_num++) 1055 { 1056 count++; 1057 /* If we haven't reached the last histogram entry counter, add 1058 in the minimum value again. This will underestimate the 1059 cumulative sum so far, because many of the counter values in this 1060 entry may have been larger than the minimum. We could add in the 1061 average value every time, but that would require an expensive 1062 divide operation. */ 1063 if (c_num + 1 < histo_bucket->num_counters) 1064 tmp_cum += histo_bucket->min_value; 1065 /* If we have reached the last histogram entry counter, then add 1066 in the entire cumulative value. */ 1067 else 1068 tmp_cum = cum + histo_bucket->cum_value; 1069 1070 /* Next walk through successive working set entries and fill in 1071 the statistics for any whose size we have reached by accumulating 1072 this histogram counter. */ 1073 while (ws_ix < NUM_GCOV_WORKING_SETS 1074 && tmp_cum >= working_set_cum_values[ws_ix]) 1075 { 1076 gcov_working_sets[ws_ix].num_counters = count; 1077 gcov_working_sets[ws_ix].min_counter 1078 = histo_bucket->min_value; 1079 ws_ix++; 1080 } 1081 } 1082 /* Finally, update the running cumulative value since we were 1083 using a temporary above. */ 1084 cum += histo_bucket->cum_value; 1085 } 1086 gcc_assert (ws_ix == NUM_GCOV_WORKING_SETS); 1087} 1088#endif /* IN_GCOV <= 0 && !IN_LIBGCOV */ 1089