00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 #ifndef GCC_GCOV_IO_H
00157 #define GCC_GCOV_IO_H
00158
00159 #include "mempool.h"
00160
00161 extern MEM_POOL *name_pool_ptr;
00162 #define GCOV_GRAPH_SUFFIX ".bbg"
00163
00164 #ifdef GCC_303
00165 #if IN_LIBGCC2
00166 #if LONG_TYPE_SIZE == GCOV_TYPE_SIZE
00167 typedef long gcov_type;
00168 #else
00169 typedef long long gcov_type;
00170 #endif
00171 #else
00172 typedef long long gcov_type;
00173 #endif
00174
00175
00176 #define GCOV_DATA_SUFFIX ".da"
00177
00178
00179 #define GCOV_DATA_MAGIC 0x67636f76
00180 #define GCOV_GRAPH_MAGIC 0x67626267
00181
00182
00183
00184
00185
00186
00187 #define GCOV_VERSION ((unsigned)858796842)
00188
00189
00190
00191
00192
00193 #define GCOV_TAG_FUNCTION ((unsigned)0x01000000)
00194 #define GCOV_TAG_BLOCKS ((unsigned)0x01410000)
00195 #define GCOV_TAG_ARCS ((unsigned)0x01430000)
00196 #define GCOV_TAG_LINES ((unsigned)0x01450000)
00197 #define GCOV_TAG_ARC_COUNTS ((unsigned)0x01a10000)
00198 #define GCOV_TAG_LOOP_HISTOGRAMS ((unsigned)0x01a30000)
00199 #define GCOV_TAG_VALUE_HISTOGRAMS ((unsigned)0x01a50000)
00200 #define GCOV_TAG_SAME_VALUE_HISTOGRAMS ((unsigned)0x01a70000)
00201 #define GCOV_TAG_OBJECT_SUMMARY ((unsigned)0xa1000000)
00202 #define GCOV_TAG_PROGRAM_SUMMARY ((unsigned)0xa3000000)
00203 #define GCOV_TAG_PLACEHOLDER_SUMMARY ((unsigned)0xa5000000)
00204 #define GCOV_TAG_INCORRECT_SUMMARY ((unsigned)0xa7000000)
00205
00206
00207
00208
00209 #define GCOV_TAG_MASK(TAG) (((TAG) - 1) ^ (TAG))
00210
00211
00212 #define GCOV_TAG_IS_SUBTAG(TAG,SUB) \
00213 (GCOV_TAG_MASK (TAG) >> 8 == GCOV_TAG_MASK (SUB) \
00214 && !(((SUB) ^ (TAG)) & ~GCOV_TAG_MASK(TAG)))
00215
00216
00217 #define GCOV_TAG_IS_SUBLEVEL(TAG,SUB) \
00218 (GCOV_TAG_MASK (TAG) > GCOV_TAG_MASK (SUB))
00219
00220
00221 #define GCOV_BLOCK_UNEXPECTED (1 << 0)
00222
00223
00224 #define GCOV_ARC_ON_TREE (1 << 0)
00225 #define GCOV_ARC_FAKE (1 << 1)
00226 #define GCOV_ARC_FALLTHROUGH (1 << 2)
00227
00228
00229
00230
00231 struct gcov_summary
00232 {
00233 unsigned checksum;
00234 unsigned runs;
00235 unsigned arcs;
00236 gcov_type arc_sum;
00237 gcov_type arc_max_one;
00238 gcov_type arc_max_sum;
00239 gcov_type arc_sum_max;
00240 };
00241
00242
00243
00244
00245
00246 struct counter_section
00247 {
00248 unsigned tag;
00249 unsigned n_counters;
00250 };
00251
00252 #if IN_LIBGCC2
00253
00254 struct counter_section_data
00255 {
00256 unsigned tag;
00257 unsigned n_counters;
00258 gcov_type *counters;
00259 };
00260
00261
00262 struct function_info
00263 {
00264 const char *name;
00265 unsigned checksum;
00266 unsigned n_counter_sections;
00267 const struct counter_section *counter_sections;
00268
00269 };
00270
00271
00272 struct gcov_info
00273 {
00274 unsigned long version;
00275 struct gcov_info *next;
00276
00277 const char *filename;
00278 long wkspc;
00279
00280 unsigned n_functions;
00281 const struct function_info *functions;
00282
00283 unsigned n_counter_sections;
00284 const struct counter_section_data *counter_sections;
00285
00286 };
00287
00288
00289 extern void __gcov_init (struct gcov_info *);
00290
00291
00292 extern void __gcov_flush (void);
00293
00294 #endif
00295
00296 #define PARAMS(P) P
00297 #define ATTRIBUTE_UNUSED
00298
00299
00300 static int gcov_write_unsigned PARAMS((FILE *, unsigned))
00301 ATTRIBUTE_UNUSED;
00302 static int gcov_write_counter PARAMS((FILE *, gcov_type))
00303 ATTRIBUTE_UNUSED;
00304 static int gcov_write_string PARAMS((FILE *, const char *, unsigned))
00305 ATTRIBUTE_UNUSED;
00306 static int gcov_read_unsigned PARAMS((FILE *, unsigned *))
00307 ATTRIBUTE_UNUSED;
00308 static int gcov_read_counter PARAMS((FILE *, gcov_type *, int))
00309 ATTRIBUTE_UNUSED;
00310 #if !IN_LIBGCC2
00311 static int gcov_read_string PARAMS((FILE *, char **, unsigned *))
00312 ATTRIBUTE_UNUSED;
00313 #endif
00314 static int gcov_read_summary PARAMS ((FILE *, struct gcov_summary *))
00315 ATTRIBUTE_UNUSED;
00316 #if IN_LIBGCC2
00317 static int gcov_write_summary PARAMS ((FILE *, unsigned,
00318 const struct gcov_summary *))
00319 ATTRIBUTE_UNUSED;
00320 #endif
00321 #define gcov_save_position(STREAM) \
00322 ftell (STREAM)
00323 #define gcov_reserve_length(STREAM) \
00324 (gcov_write_unsigned (STREAM, 0) ? 0 : ftell (STREAM) - 4)
00325 static int gcov_write_length PARAMS((FILE *, long))
00326 ATTRIBUTE_UNUSED;
00327 #define gcov_resync(STREAM, BASE, LENGTH) \
00328 fseek (STREAM, BASE + (long)LENGTH, SEEK_SET)
00329 #define gcov_skip(STREAM, LENGTH) \
00330 fseek (STREAM, LENGTH, SEEK_CUR)
00331 #define gcov_skip_string(STREAM, LENGTH) \
00332 fseek (STREAM, (LENGTH) + 4 - ((LENGTH) & 3), SEEK_CUR)
00333 typedef int (*merger_function) PARAMS ((FILE *, gcov_type *, unsigned));
00334 static int same_value_histograms_merger PARAMS ((FILE *, gcov_type *, unsigned))
00335 ATTRIBUTE_UNUSED;
00336 static merger_function profile_merger_for_tag PARAMS ((unsigned))
00337 ATTRIBUTE_UNUSED;
00338
00339
00340
00341
00342
00343 static int
00344 gcov_write_unsigned (
00345 FILE *file,
00346 unsigned value)
00347 {
00348 char buffer[4];
00349 unsigned ix;
00350
00351
00352
00353 for (ix = sizeof (buffer); ix--; )
00354 {
00355 buffer[ix] = value;
00356 value >>= 8;
00357 }
00358 return ((sizeof (value) > sizeof (buffer) && value)
00359 || fwrite (buffer, sizeof (buffer), 1, file) != 1);
00360 }
00361
00362
00363
00364
00365
00366 static int
00367 gcov_write_counter (
00368 FILE *file,
00369 gcov_type value)
00370 {
00371 char buffer[8];
00372 unsigned ix;
00373
00374 for (ix = sizeof (buffer); ix--; )
00375 {
00376 buffer[ix] = value;
00377 value >>= 8;
00378 }
00379 return ((sizeof (value) > sizeof (buffer) && value != 0 && value != -1)
00380 || fwrite (buffer, sizeof (buffer), 1, file) != 1);
00381 }
00382
00383
00384
00385
00386 static int
00387 gcov_write_string (
00388 FILE *file,
00389 const char *string,
00390 unsigned length)
00391 {
00392 unsigned pad = 0;
00393
00394 if (string)
00395 return (gcov_write_unsigned (file, length)
00396 || fwrite (string, length, 1, file) != 1
00397 || fwrite (&pad, 4 - (length & 3), 1, file) != 1);
00398 else
00399 return gcov_write_unsigned (file, 0);
00400 }
00401
00402
00403
00404
00405 static int
00406 gcov_read_unsigned (
00407 FILE *file,
00408 unsigned *value_p)
00409 {
00410 unsigned value = 0;
00411 unsigned ix;
00412 unsigned char buffer[4];
00413
00414 if (fread (buffer, sizeof (buffer), 1, file) != 1)
00415 return 1;
00416 for (ix = sizeof (value); ix < sizeof (buffer); ix++)
00417 if (buffer[ix])
00418 return 1;
00419 for (ix = 0; ix != sizeof (buffer); ix++)
00420 {
00421 value <<= 8;
00422 value |= buffer[ix];
00423 }
00424 *value_p = value;
00425 return 0;
00426 }
00427
00428
00429
00430
00431
00432 static int
00433 gcov_read_counter (
00434 FILE *file,
00435 gcov_type *value_p,
00436 int may_be_negative)
00437 {
00438 gcov_type value = 0;
00439 unsigned ix;
00440 unsigned char buffer[8];
00441
00442 if (fread (buffer, sizeof (buffer), 1, file) != 1)
00443 return 1;
00444 for (ix = sizeof (value); ix < sizeof (buffer); ix++)
00445 if (buffer[ix])
00446 return 1;
00447 for (ix = 0; ix != sizeof (buffer); ix++)
00448 {
00449 value <<= 8;
00450 value |= buffer[ix];
00451 }
00452
00453 *value_p = value;
00454 return !may_be_negative && value < 0;
00455 }
00456
00457 static int
00458 same_value_histograms_merger (
00459 FILE *da_file,
00460 gcov_type *counters,
00461 unsigned n_counters)
00462 {
00463 unsigned i, n_measures;
00464 gcov_type value, counter, all;
00465
00466 if (n_counters % 3)
00467 return 1;
00468
00469 n_measures = n_counters / 3;
00470 for (i = 0; i < n_measures; i++, counters += 3)
00471 {
00472 if (gcov_read_counter (da_file, &value, 1)
00473 || gcov_read_counter (da_file, &counter, 0)
00474 || gcov_read_counter (da_file, &all, 0))
00475 return 1;
00476
00477 if (counters[0] == value)
00478 counters[1] += counter;
00479 else if (counter > counters[1])
00480 {
00481 counters[0] = value;
00482 counters[1] = counter - counters[1];
00483 }
00484 else
00485 counters[1] -= counter;
00486 counters[2] += all;
00487 }
00488 return 0;
00489 }
00490
00491 static merger_function
00492 profile_merger_for_tag (
00493 unsigned tag)
00494 {
00495 switch (tag)
00496 {
00497 case GCOV_TAG_SAME_VALUE_HISTOGRAMS:
00498 return same_value_histograms_merger;
00499 default:
00500 return 0;
00501 }
00502 }
00503
00504 #if !IN_LIBGCC2
00505
00506
00507
00508
00509
00510 static int
00511 gcov_read_string (
00512 FILE *file,
00513 char **string_p,
00514 unsigned *length_p)
00515 {
00516 unsigned length;
00517
00518 if (gcov_read_unsigned (file, &length))
00519 return 1;
00520
00521 if (length_p)
00522 *length_p = length;
00523 free (*string_p);
00524
00525 *string_p = NULL;
00526 if (!length)
00527 return 0;
00528
00529 length += 4 - (length & 3);
00530 *string_p = (char *) CXX_NEW_ARRAY (char, length, name_pool_ptr);
00531
00532 return fread (*string_p, length, 1, file) != 1;
00533
00534 }
00535
00536 #endif
00537
00538
00539
00540
00541
00542 static int
00543 gcov_write_length (
00544 FILE *file,
00545 long place)
00546 {
00547 long here = ftell (file);
00548 int result = (!place || fseek (file, place, SEEK_SET)
00549 || gcov_write_unsigned (file, here - place - 4));
00550 if (fseek (file, here, SEEK_SET))
00551 result = 1;
00552 return result;
00553 }
00554
00555 #define GCOV_SUMMARY_LENGTH 44
00556 static int
00557 gcov_read_summary (
00558 FILE *da_file,
00559 struct gcov_summary *summary)
00560 {
00561 return (gcov_read_unsigned (da_file, &summary->checksum)
00562 || gcov_read_unsigned (da_file, &summary->runs)
00563 || gcov_read_unsigned (da_file, &summary->arcs)
00564 || gcov_read_counter (da_file, &summary->arc_sum, 0)
00565 || gcov_read_counter (da_file, &summary->arc_max_one, 0)
00566 || gcov_read_counter (da_file, &summary->arc_max_sum, 0)
00567 || gcov_read_counter (da_file, &summary->arc_sum_max, 0));
00568 }
00569
00570 #if IN_LIBGCC2
00571 static int
00572 gcov_write_summary (
00573 FILE *da_file,
00574 unsigned tag,
00575 const struct gcov_summary *summary)
00576 {
00577 long base;
00578
00579 return (gcov_write_unsigned (da_file, tag)
00580 || !(base = gcov_reserve_length (da_file))
00581 || gcov_write_unsigned (da_file, summary->checksum)
00582 || gcov_write_unsigned (da_file, summary->runs)
00583 || gcov_write_unsigned (da_file, summary->arcs)
00584 || gcov_write_counter (da_file, summary->arc_sum)
00585 || gcov_write_counter (da_file, summary->arc_max_one)
00586 || gcov_write_counter (da_file, summary->arc_max_sum)
00587 || gcov_write_counter (da_file, summary->arc_sum_max)
00588 || gcov_write_length (da_file, base));
00589 }
00590 #endif
00591 #else
00592 #include <stdio.h>
00593 #include <sys/types.h>
00594
00595 #define PARAMS(P) P
00596 #define ATTRIBUTE_UNUSED
00597 typedef long long gcov_type;
00598
00599 static int __fetch_long PARAMS ((long *, char *, size_t))
00600 ATTRIBUTE_UNUSED;
00601 static int __read_long PARAMS ((long *, FILE *, size_t))
00602 ATTRIBUTE_UNUSED;
00603 static int __write_long PARAMS ((long, FILE *, size_t))
00604 ATTRIBUTE_UNUSED;
00605 static int __fetch_gcov_type PARAMS ((gcov_type *, char *, size_t))
00606 ATTRIBUTE_UNUSED;
00607 static int __store_gcov_type PARAMS ((gcov_type, char *, size_t))
00608 ATTRIBUTE_UNUSED;
00609 static int __read_gcov_type PARAMS ((gcov_type *, FILE *, size_t))
00610 ATTRIBUTE_UNUSED;
00611 static int __write_gcov_type PARAMS ((gcov_type, FILE *, size_t))
00612 ATTRIBUTE_UNUSED;
00613 static int __write_gcov_string PARAMS ((const char *, size_t, FILE*, long))
00614 ATTRIBUTE_UNUSED;
00615 static int __read_gcov_string PARAMS ((char *, size_t, FILE*, long))
00616 ATTRIBUTE_UNUSED;
00617
00618
00619
00620
00621
00622 static int
00623 __store_gcov_type (
00624 gcov_type value,
00625 char *dest,
00626 size_t bytes)
00627 {
00628 int upper_bit = (value < 0 ? 128 : 0);
00629 size_t i;
00630
00631 if (value < 0)
00632 {
00633 gcov_type oldvalue = value;
00634 value = -value;
00635 if (oldvalue != -value)
00636 return 1;
00637 }
00638
00639 for(i = 0 ; i < (sizeof (value) < bytes ? sizeof (value) : bytes) ; i++) {
00640 dest[i] = value & (i == (bytes - 1) ? 127 : 255);
00641 value = value / 256;
00642 }
00643
00644 if (value && value != -1)
00645 return 1;
00646
00647 for(; i < bytes ; i++)
00648 dest[i] = 0;
00649 dest[bytes - 1] |= upper_bit;
00650 return 0;
00651 }
00652
00653
00654
00655
00656
00657 static int
00658 __fetch_gcov_type (
00659 gcov_type *dest,
00660 char *source,
00661 size_t bytes)
00662 {
00663 gcov_type value = 0;
00664 int i;
00665
00666 for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
00667 if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
00668 return 1;
00669
00670 for (; i >= 0; i--)
00671 value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 :
00672 255));
00673
00674 if ((source[bytes - 1] & 128) && (value > 0))
00675 value = - value;
00676
00677 *dest = value;
00678 return 0;
00679 }
00680
00681 static int
00682 __fetch_long (
00683 long *dest,
00684 char *source,
00685 size_t bytes)
00686 {
00687 long value = 0;
00688 int i;
00689
00690 for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
00691 if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
00692 return 1;
00693
00694 for (; i >= 0; i--)
00695 value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 :
00696 255));
00697
00698 if ((source[bytes - 1] & 128) && (value > 0))
00699 value = - value;
00700
00701 *dest = value;
00702 return 0;
00703 }
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 static int
00715 __write_gcov_type (
00716 gcov_type value,
00717 FILE *file,
00718 size_t bytes)
00719 {
00720 char c[10];
00721
00722 if (bytes > 10 || __store_gcov_type (value, c, bytes))
00723 return 1;
00724 else
00725 return fwrite(c, 1, bytes, file) != bytes;
00726 }
00727
00728 static int
00729 __write_long (
00730 long value,
00731 FILE *file,
00732 size_t bytes)
00733 {
00734 char c[10];
00735
00736
00737
00738 if (bytes > 10 || __store_gcov_type ((gcov_type)value, c, bytes))
00739 return 1;
00740 else
00741 return fwrite(c, 1, bytes, file) != bytes;
00742 }
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753 static int
00754 __read_gcov_type (
00755 gcov_type *dest,
00756 FILE *file,
00757 size_t bytes)
00758 {
00759 char c[10];
00760
00761 if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
00762 return 1;
00763 else
00764 return __fetch_gcov_type (dest, c, bytes);
00765 }
00766
00767 static int
00768 __read_long (
00769 long *dest,
00770 FILE *file,
00771 size_t bytes)
00772 {
00773 char c[10];
00774
00775 if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
00776 return 1;
00777 else
00778 return __fetch_long (dest, c, bytes);
00779 }
00780
00781
00782
00783
00784 static int
00785 __write_gcov_string (
00786 const char *string,
00787 size_t length,
00788 FILE *file,
00789 long delim)
00790 {
00791 size_t temp = length + 1;
00792
00793
00794 if (__write_long (delim, file, 4) != 0)
00795 return 1;
00796
00797 if (__write_long (length, file, 4) != 0)
00798 return 1;
00799
00800
00801 if (fwrite (string, temp, 1, file) != 1)
00802 return 1;
00803
00804 temp &= 3;
00805
00806 if (temp)
00807 {
00808 char c[4];
00809
00810 c[0] = c[1] = c[2] = c[3] = 0;
00811
00812 if (fwrite (c, sizeof (char), 4 - temp, file) != 4 - temp)
00813 return 1;
00814 }
00815
00816 if (__write_long (delim, file, 4) != 0)
00817 return 1;
00818
00819 return 0;
00820 }
00821
00822
00823
00824
00825 static int
00826 __read_gcov_string (
00827 char *string,
00828 size_t max_length,
00829 FILE *file,
00830 long delim)
00831 {
00832 long delim_from_file;
00833 long length;
00834 long read_length;
00835 long tmp;
00836
00837 if (__read_long (&delim_from_file, file, 4) != 0)
00838 return 1;
00839
00840 if (delim_from_file != delim)
00841 return 1;
00842
00843 if (__read_long (&length, file, 4) != 0)
00844 return 1;
00845 if (length > (long) max_length)
00846 read_length = max_length;
00847 else
00848 read_length = length;
00849
00850 tmp = (((length + 1) - 1) / 4 + 1) * 4;
00851
00852
00853 if (fread (string, read_length, 1, file) != 1)
00854 return 1;
00855
00856 string[read_length] = 0;
00857
00858 if (fseek (file, tmp - read_length, SEEK_CUR) < 0)
00859 return 1;
00860
00861 if (__read_long (&delim_from_file, file, 4) != 0)
00862 return 1;
00863
00864 if (delim_from_file != delim)
00865 return 1;
00866
00867 return 0;
00868 }
00869
00870 #endif
00871 #endif