1132718Skan/* File format for coverage information 2132718Skan Copyright (C) 1996, 1997, 1998, 2000, 2002, 3169689Skan 2003, 2004, 2005 Free Software Foundation, Inc. 450397Sobrien Contributed by Bob Manson <manson@cygnus.com>. 5132718Skan Completely remangled by Nathan Sidwell <nathan@codesourcery.com>. 650397Sobrien 790075SobrienThis file is part of GCC. 850397Sobrien 990075SobrienGCC is free software; you can redistribute it and/or modify it under 1090075Sobrienthe terms of the GNU General Public License as published by the Free 1190075SobrienSoftware Foundation; either version 2, or (at your option) any later 1290075Sobrienversion. 1350397Sobrien 1490075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1590075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1690075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1790075Sobrienfor more details. 1850397Sobrien 1950397SobrienYou should have received a copy of the GNU General Public License 2090075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 21169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 22169689Skan02110-1301, USA. */ 2350397Sobrien 24117395Skan/* As a special exception, if you link this library with other files, 25117395Skan some of which are compiled with GCC, to produce an executable, 26117395Skan this library does not by itself cause the resulting executable 27117395Skan to be covered by the GNU General Public License. 28117395Skan This exception does not however invalidate any other reasons why 29132718Skan the executable file might be covered by the GNU General Public License. */ 30117395Skan 31132718Skan/* Coverage information is held in two files. A notes file, which is 32169689Skan generated by the compiler, and a data file, which is generated by 33169689Skan the program under test. Both files use a similar structure. We do 34169689Skan not attempt to make these files backwards compatible with previous 35169689Skan versions, as you only need coverage information when developing a 36169689Skan program. We do hold version information, so that mismatches can be 37169689Skan detected, and we use a format that allows tools to skip information 38169689Skan they do not understand or are not interested in. 39132718Skan 40132718Skan Numbers are recorded in the 32 bit unsigned binary form of the 41132718Skan endianness of the machine generating the file. 64 bit numbers are 42132718Skan stored as two 32 bit numbers, the low part first. Strings are 43132718Skan padded with 1 to 4 NUL bytes, to bring the length up to a multiple 44132718Skan of 4. The number of 4 bytes is stored, followed by the padded 45169689Skan string. Zero length and NULL strings are simply stored as a length 46169689Skan of zero (they have no trailing NUL or padding). 47132718Skan 48132718Skan int32: byte3 byte2 byte1 byte0 | byte0 byte1 byte2 byte3 49132718Skan int64: int32:low int32:high 50132718Skan string: int32:0 | int32:length char* char:0 padding 51132718Skan padding: | char:0 | char:0 char:0 | char:0 char:0 char:0 52132718Skan item: int32 | int64 | string 53132718Skan 54132718Skan The basic format of the files is 55132718Skan 56132718Skan file : int32:magic int32:version int32:stamp record* 57132718Skan 58132718Skan The magic ident is different for the notes and the data files. The 59132718Skan magic ident is used to determine the endianness of the file, when 60132718Skan reading. The version is the same for both files and is derived 61132718Skan from gcc's version number. The stamp value is used to synchronize 62132718Skan note and data files and to synchronize merging within a data 63132718Skan file. It need not be an absolute time stamp, merely a ticker that 64132718Skan increments fast enough and cycles slow enough to distinguish 65132718Skan different compile/run/compile cycles. 66132718Skan 67132718Skan Although the ident and version are formally 32 bit numbers, they 68132718Skan are derived from 4 character ASCII strings. The version number 69132718Skan consists of the single character major version number, a two 70132718Skan character minor version number (leading zero for versions less than 71132718Skan 10), and a single character indicating the status of the release. 72132718Skan That will be 'e' experimental, 'p' prerelease and 'r' for release. 73132718Skan Because, by good fortune, these are in alphabetical order, string 74132718Skan collating can be used to compare version strings. Be aware that 75132718Skan the 'e' designation will (naturally) be unstable and might be 76132718Skan incompatible with itself. For gcc 3.4 experimental, it would be 77132718Skan '304e' (0x33303465). When the major version reaches 10, the 78132718Skan letters A-Z will be used. Assuming minor increments releases every 79132718Skan 6 months, we have to make a major increment every 50 years. 80132718Skan Assuming major increments releases every 5 years, we're ok for the 81132718Skan next 155 years -- good enough for me. 82132718Skan 83132718Skan A record has a tag, length and variable amount of data. 84132718Skan 85132718Skan record: header data 86132718Skan header: int32:tag int32:length 87132718Skan data: item* 88132718Skan 89132718Skan Records are not nested, but there is a record hierarchy. Tag 90132718Skan numbers reflect this hierarchy. Tags are unique across note and 91132718Skan data files. Some record types have a varying amount of data. The 92132718Skan LENGTH is the number of 4bytes that follow and is usually used to 93132718Skan determine how much data. The tag value is split into 4 8-bit 94132718Skan fields, one for each of four possible levels. The most significant 95132718Skan is allocated first. Unused levels are zero. Active levels are 96132718Skan odd-valued, so that the LSB of the level is one. A sub-level 97132718Skan incorporates the values of its superlevels. This formatting allows 98132718Skan you to determine the tag hierarchy, without understanding the tags 99132718Skan themselves, and is similar to the standard section numbering used 100132718Skan in technical documents. Level values [1..3f] are used for common 101132718Skan tags, values [41..9f] for the notes file and [a1..ff] for the data 102132718Skan file. 103132718Skan 104132718Skan The basic block graph file contains the following records 105132718Skan note: unit function-graph* 106132718Skan unit: header int32:checksum string:source 107132718Skan function-graph: announce_function basic_blocks {arcs | lines}* 108132718Skan announce_function: header int32:ident int32:checksum 109132718Skan string:name string:source int32:lineno 110132718Skan basic_block: header int32:flags* 111132718Skan arcs: header int32:block_no arc* 112132718Skan arc: int32:dest_block int32:flags 113132718Skan lines: header int32:block_no line* 114132718Skan int32:0 string:NULL 115132718Skan line: int32:line_no | int32:0 string:filename 116132718Skan 117132718Skan The BASIC_BLOCK record holds per-bb flags. The number of blocks 118132718Skan can be inferred from its data length. There is one ARCS record per 119132718Skan basic block. The number of arcs from a bb is implicit from the 120132718Skan data length. It enumerates the destination bb and per-arc flags. 121132718Skan There is one LINES record per basic block, it enumerates the source 122132718Skan lines which belong to that basic block. Source file names are 123132718Skan introduced by a line number of 0, following lines are from the new 124132718Skan source file. The initial source file for the function is NULL, but 125132718Skan the current source file should be remembered from one LINES record 126132718Skan to the next. The end of a block is indicated by an empty filename 127132718Skan - this does not reset the current source file. Note there is no 128132718Skan ordering of the ARCS and LINES records: they may be in any order, 129132718Skan interleaved in any manner. The current filename follows the order 130132718Skan the LINES records are stored in the file, *not* the ordering of the 131132718Skan blocks they are for. 132132718Skan 133132718Skan The data file contains the following records. 134132718Skan data: {unit function-data* summary:object summary:program*}* 135132718Skan unit: header int32:checksum 136132718Skan function-data: announce_function arc_counts 137132718Skan announce_function: header int32:ident int32:checksum 138132718Skan arc_counts: header int64:count* 139132718Skan summary: int32:checksum {count-summary}GCOV_COUNTERS 140132718Skan count-summary: int32:num int32:runs int64:sum 141132718Skan int64:max int64:sum_max 142132718Skan 143132718Skan The ANNOUNCE_FUNCTION record is the same as that in the note file, 144132718Skan but without the source location. The ARC_COUNTS gives the counter 145132718Skan values for those arcs that are instrumented. The SUMMARY records 146132718Skan give information about the whole object file and about the whole 147132718Skan program. The checksum is used for whole program summaries, and 148132718Skan disambiguates different programs which include the same 149132718Skan instrumented object file. There may be several program summaries, 150132718Skan each with a unique checksum. The object summary's checksum is zero. 151132718Skan Note that the data file might contain information from several runs 152132718Skan concatenated, or the data might be merged. 153132718Skan 154132718Skan This file is included by both the compiler, gcov tools and the 155132718Skan runtime support library libgcov. IN_LIBGCOV and IN_GCOV are used to 156132718Skan distinguish which case is which. If IN_LIBGCOV is nonzero, 157132718Skan libgcov is being built. If IN_GCOV is nonzero, the gcov tools are 158132718Skan being built. Otherwise the compiler is being built. IN_GCOV may be 159132718Skan positive or negative. If positive, we are compiling a tool that 160132718Skan requires additional functions (see the code for knowledge of what 161132718Skan those functions are). */ 162132718Skan 16390075Sobrien#ifndef GCC_GCOV_IO_H 16490075Sobrien#define GCC_GCOV_IO_H 16550397Sobrien 166132718Skan#if IN_LIBGCOV 167132718Skan/* About the target */ 16850397Sobrien 169132718Skan#if BITS_PER_UNIT == 8 170132718Skantypedef unsigned gcov_unsigned_t __attribute__ ((mode (SI))); 171132718Skantypedef unsigned gcov_position_t __attribute__ ((mode (SI))); 172132718Skan#if LONG_LONG_TYPE_SIZE > 32 173132718Skantypedef signed gcov_type __attribute__ ((mode (DI))); 174132718Skan#else 175132718Skantypedef signed gcov_type __attribute__ ((mode (SI))); 176132718Skan#endif 177132718Skan#else 178132718Skan#if BITS_PER_UNIT == 16 179132718Skantypedef unsigned gcov_unsigned_t __attribute__ ((mode (HI))); 180132718Skantypedef unsigned gcov_position_t __attribute__ ((mode (HI))); 181132718Skan#if LONG_LONG_TYPE_SIZE > 32 182132718Skantypedef signed gcov_type __attribute__ ((mode (SI))); 183132718Skan#else 184132718Skantypedef signed gcov_type __attribute__ ((mode (HI))); 185132718Skan#endif 186132718Skan#else 187132718Skantypedef unsigned gcov_unsigned_t __attribute__ ((mode (QI))); 188132718Skantypedef unsigned gcov_position_t __attribute__ ((mode (QI))); 189132718Skan#if LONG_LONG_TYPE_SIZE > 32 190132718Skantypedef signed gcov_type __attribute__ ((mode (HI))); 191132718Skan#else 192132718Skantypedef signed gcov_type __attribute__ ((mode (QI))); 193132718Skan#endif 194132718Skan#endif 195132718Skan#endif 19650397Sobrien 19750397Sobrien 198169689Skan#if defined (TARGET_POSIX_IO) 199132718Skan#define GCOV_LOCKED 1 200132718Skan#else 201132718Skan#define GCOV_LOCKED 0 202132718Skan#endif 20350397Sobrien 204132718Skan#else /* !IN_LIBGCOV */ 205132718Skan/* About the host */ 20650397Sobrien 207132718Skantypedef unsigned gcov_unsigned_t; 208132718Skantypedef unsigned gcov_position_t; 209132718Skan/* gcov_type is typedef'd elsewhere for the compiler */ 210132718Skan#if IN_GCOV 211132718Skan#define GCOV_LINKAGE static 212132718Skantypedef HOST_WIDEST_INT gcov_type; 213132718Skan#if IN_GCOV > 0 214132718Skan#include <sys/types.h> 215132718Skan#endif 216132718Skan#else /*!IN_GCOV */ 217169689Skan#define GCOV_TYPE_SIZE (LONG_LONG_TYPE_SIZE > 32 ? 64 : 32) 218132718Skan#endif 21950397Sobrien 220132718Skan#if defined (HOST_HAS_F_SETLKW) 221132718Skan#define GCOV_LOCKED 1 222132718Skan#else 223132718Skan#define GCOV_LOCKED 0 224132718Skan#endif 22550397Sobrien 226132718Skan#endif /* !IN_LIBGCOV */ 22750397Sobrien 228146895Skan/* In gcov we want function linkage to be static. In the compiler we want 229146895Skan it extern, so that they can be accessed from elsewhere. In libgcov we 230146895Skan need these functions to be extern, so prefix them with __gcov. In 231146895Skan libgcov they must also be hidden so that the instance in the executable 232146895Skan is not also used in a DSO. */ 233132718Skan#if IN_LIBGCOV 234146895Skan 235169689Skan#include "tconfig.h" 236146895Skan 237132718Skan#define gcov_var __gcov_var 238132718Skan#define gcov_open __gcov_open 239132718Skan#define gcov_close __gcov_close 240132718Skan#define gcov_write_tag_length __gcov_write_tag_length 241132718Skan#define gcov_position __gcov_position 242132718Skan#define gcov_seek __gcov_seek 243132718Skan#define gcov_rewrite __gcov_rewrite 244132718Skan#define gcov_is_error __gcov_is_error 245132718Skan#define gcov_write_unsigned __gcov_write_unsigned 246132718Skan#define gcov_write_counter __gcov_write_counter 247132718Skan#define gcov_write_summary __gcov_write_summary 248132718Skan#define gcov_read_unsigned __gcov_read_unsigned 249132718Skan#define gcov_read_counter __gcov_read_counter 250132718Skan#define gcov_read_summary __gcov_read_summary 25150397Sobrien 252132718Skan/* Poison these, so they don't accidentally slip in. */ 253132718Skan#pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length 254132718Skan#pragma GCC poison gcov_read_string gcov_sync gcov_time gcov_magic 25590075Sobrien 256146895Skan#ifdef HAVE_GAS_HIDDEN 257146895Skan#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden"))) 258146895Skan#else 259146895Skan#define ATTRIBUTE_HIDDEN 260132718Skan#endif 26190075Sobrien 262146895Skan#else 263146895Skan 264146895Skan#define ATTRIBUTE_HIDDEN 265146895Skan 266146895Skan#endif 267146895Skan 268132718Skan#ifndef GCOV_LINKAGE 269132718Skan#define GCOV_LINKAGE extern 270132718Skan#endif 27190075Sobrien 272132718Skan/* File suffixes. */ 273132718Skan#define GCOV_DATA_SUFFIX ".gcda" 274132718Skan#define GCOV_NOTE_SUFFIX ".gcno" 27590075Sobrien 276132718Skan/* File magic. Must not be palindromes. */ 277132718Skan#define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */ 278132718Skan#define GCOV_NOTE_MAGIC ((gcov_unsigned_t)0x67636e6f) /* "gcno" */ 27990075Sobrien 280132718Skan/* gcov-iov.h is automatically generated by the makefile from 281132718Skan version.c, it looks like 282132718Skan #define GCOV_VERSION ((gcov_unsigned_t)0x89abcdef) 283132718Skan*/ 284132718Skan#include "gcov-iov.h" 28550397Sobrien 286132718Skan/* Convert a magic or version number to a 4 character string. */ 287132718Skan#define GCOV_UNSIGNED2STRING(ARRAY,VALUE) \ 288132718Skan ((ARRAY)[0] = (char)((VALUE) >> 24), \ 289132718Skan (ARRAY)[1] = (char)((VALUE) >> 16), \ 290132718Skan (ARRAY)[2] = (char)((VALUE) >> 8), \ 291132718Skan (ARRAY)[3] = (char)((VALUE) >> 0)) 29250397Sobrien 293132718Skan/* The record tags. Values [1..3f] are for tags which may be in either 294132718Skan file. Values [41..9f] for those in the note file and [a1..ff] for 295169689Skan the data file. The tag value zero is used as an explicit end of 296169689Skan file marker -- it is not required to be present. */ 29750397Sobrien 298132718Skan#define GCOV_TAG_FUNCTION ((gcov_unsigned_t)0x01000000) 299132718Skan#define GCOV_TAG_FUNCTION_LENGTH (2) 300132718Skan#define GCOV_TAG_BLOCKS ((gcov_unsigned_t)0x01410000) 301132718Skan#define GCOV_TAG_BLOCKS_LENGTH(NUM) (NUM) 302132718Skan#define GCOV_TAG_BLOCKS_NUM(LENGTH) (LENGTH) 303132718Skan#define GCOV_TAG_ARCS ((gcov_unsigned_t)0x01430000) 304132718Skan#define GCOV_TAG_ARCS_LENGTH(NUM) (1 + (NUM) * 2) 305132718Skan#define GCOV_TAG_ARCS_NUM(LENGTH) (((LENGTH) - 1) / 2) 306132718Skan#define GCOV_TAG_LINES ((gcov_unsigned_t)0x01450000) 307132718Skan#define GCOV_TAG_COUNTER_BASE ((gcov_unsigned_t)0x01a10000) 308132718Skan#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2) 309132718Skan#define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2) 310132718Skan#define GCOV_TAG_OBJECT_SUMMARY ((gcov_unsigned_t)0xa1000000) 311132718Skan#define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000) 312132718Skan#define GCOV_TAG_SUMMARY_LENGTH \ 313132718Skan (1 + GCOV_COUNTERS_SUMMABLE * (2 + 3 * 2)) 31450397Sobrien 315132718Skan/* Counters that are collected. */ 316132718Skan#define GCOV_COUNTER_ARCS 0 /* Arc transitions. */ 317132718Skan#define GCOV_COUNTERS_SUMMABLE 1 /* Counters which can be 318132718Skan summaried. */ 319132718Skan#define GCOV_FIRST_VALUE_COUNTER 1 /* The first of counters used for value 320132718Skan profiling. They must form a consecutive 321132718Skan interval and their order must match 322132718Skan the order of HIST_TYPEs in 323132718Skan value-prof.h. */ 324132718Skan#define GCOV_COUNTER_V_INTERVAL 1 /* Histogram of value inside an interval. */ 325132718Skan#define GCOV_COUNTER_V_POW2 2 /* Histogram of exact power2 logarithm 326132718Skan of a value. */ 327132718Skan#define GCOV_COUNTER_V_SINGLE 3 /* The most common value of expression. */ 328132718Skan#define GCOV_COUNTER_V_DELTA 4 /* The most common difference between 329132718Skan consecutive values of expression. */ 330132718Skan#define GCOV_LAST_VALUE_COUNTER 4 /* The last of counters used for value 331132718Skan profiling. */ 332132718Skan#define GCOV_COUNTERS 5 33350397Sobrien 334132718Skan/* Number of counters used for value profiling. */ 335132718Skan#define GCOV_N_VALUE_COUNTERS \ 336132718Skan (GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1) 337132718Skan 338132718Skan /* A list of human readable names of the counters */ 339132718Skan#define GCOV_COUNTER_NAMES {"arcs", "interval", "pow2", "single", "delta"} 340132718Skan 341132718Skan /* Names of merge functions for counters. */ 342132718Skan#define GCOV_MERGE_FUNCTIONS {"__gcov_merge_add", \ 343132718Skan "__gcov_merge_add", \ 344132718Skan "__gcov_merge_add", \ 345132718Skan "__gcov_merge_single", \ 346132718Skan "__gcov_merge_delta"} 347132718Skan 348132718Skan/* Convert a counter index to a tag. */ 349132718Skan#define GCOV_TAG_FOR_COUNTER(COUNT) \ 350132718Skan (GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17)) 351132718Skan/* Convert a tag to a counter. */ 352132718Skan#define GCOV_COUNTER_FOR_TAG(TAG) \ 353132718Skan ((unsigned)(((TAG) - GCOV_TAG_COUNTER_BASE) >> 17)) 354132718Skan/* Check whether a tag is a counter tag. */ 355132718Skan#define GCOV_TAG_IS_COUNTER(TAG) \ 356132718Skan (!((TAG) & 0xFFFF) && GCOV_COUNTER_FOR_TAG (TAG) < GCOV_COUNTERS) 35750397Sobrien 358132718Skan/* The tag level mask has 1's in the position of the inner levels, & 359132718Skan the lsb of the current level, and zero on the current and outer 360132718Skan levels. */ 361132718Skan#define GCOV_TAG_MASK(TAG) (((TAG) - 1) ^ (TAG)) 36250397Sobrien 363132718Skan/* Return nonzero if SUB is an immediate subtag of TAG. */ 364132718Skan#define GCOV_TAG_IS_SUBTAG(TAG,SUB) \ 365132718Skan (GCOV_TAG_MASK (TAG) >> 8 == GCOV_TAG_MASK (SUB) \ 366132718Skan && !(((SUB) ^ (TAG)) & ~GCOV_TAG_MASK(TAG))) 36750397Sobrien 368132718Skan/* Return nonzero if SUB is at a sublevel to TAG. */ 369132718Skan#define GCOV_TAG_IS_SUBLEVEL(TAG,SUB) \ 370132718Skan (GCOV_TAG_MASK (TAG) > GCOV_TAG_MASK (SUB)) 37190075Sobrien 372132718Skan/* Basic block flags. */ 373132718Skan#define GCOV_BLOCK_UNEXPECTED (1 << 1) 37490075Sobrien 375132718Skan/* Arc flags. */ 376132718Skan#define GCOV_ARC_ON_TREE (1 << 0) 377132718Skan#define GCOV_ARC_FAKE (1 << 1) 378132718Skan#define GCOV_ARC_FALLTHROUGH (1 << 2) 37950397Sobrien 380132718Skan/* Structured records. */ 38150397Sobrien 382132718Skan/* Cumulative counter data. */ 383132718Skanstruct gcov_ctr_summary 384132718Skan{ 385132718Skan gcov_unsigned_t num; /* number of counters. */ 386132718Skan gcov_unsigned_t runs; /* number of program runs */ 387132718Skan gcov_type sum_all; /* sum of all counters accumulated. */ 388132718Skan gcov_type run_max; /* maximum value on a single run. */ 389132718Skan gcov_type sum_max; /* sum of individual run max values. */ 390132718Skan}; 39150397Sobrien 392132718Skan/* Object & program summary record. */ 393132718Skanstruct gcov_summary 394132718Skan{ 395132718Skan gcov_unsigned_t checksum; /* checksum of program */ 396132718Skan struct gcov_ctr_summary ctrs[GCOV_COUNTERS_SUMMABLE]; 397132718Skan}; 39850397Sobrien 399132718Skan/* Structures embedded in coveraged program. The structures generated 400132718Skan by write_profile must match these. */ 40150397Sobrien 402132718Skan#if IN_LIBGCOV 403132718Skan/* Information about a single function. This uses the trailing array 404132718Skan idiom. The number of counters is determined from the counter_mask 405132718Skan in gcov_info. We hold an array of function info, so have to 406132718Skan explicitly calculate the correct array stride. */ 407132718Skanstruct gcov_fn_info 40890075Sobrien{ 409132718Skan gcov_unsigned_t ident; /* unique ident of function */ 410132718Skan gcov_unsigned_t checksum; /* function checksum */ 411132718Skan unsigned n_ctrs[0]; /* instrumented counters */ 412132718Skan}; 41390075Sobrien 414132718Skan/* Type of function used to merge counters. */ 415132718Skantypedef void (*gcov_merge_fn) (gcov_type *, gcov_unsigned_t); 41690075Sobrien 417132718Skan/* Information about counters. */ 418132718Skanstruct gcov_ctr_info 41950397Sobrien{ 420132718Skan gcov_unsigned_t num; /* number of counters. */ 421132718Skan gcov_type *values; /* their values. */ 422132718Skan gcov_merge_fn merge; /* The function used to merge them. */ 423132718Skan}; 42450397Sobrien 425132718Skan/* Information about a single object file. */ 426132718Skanstruct gcov_info 427132718Skan{ 428132718Skan gcov_unsigned_t version; /* expected version number */ 429132718Skan struct gcov_info *next; /* link to next, used by libgcov */ 43050397Sobrien 431132718Skan gcov_unsigned_t stamp; /* uniquifying time stamp */ 432132718Skan const char *filename; /* output file name */ 433132718Skan 434132718Skan unsigned n_functions; /* number of functions */ 435132718Skan const struct gcov_fn_info *functions; /* table of functions */ 436117395Skan 437132718Skan unsigned ctr_mask; /* mask of counters instrumented. */ 438132718Skan struct gcov_ctr_info counts[0]; /* count data. The number of bits 439132718Skan set in the ctr_mask field 440132718Skan determines how big this array 441132718Skan is. */ 442132718Skan}; 443117395Skan 444132718Skan/* Register a new object file module. */ 445146895Skanextern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN; 446117395Skan 447132718Skan/* Called before fork, to avoid double counting. */ 448146895Skanextern void __gcov_flush (void) ATTRIBUTE_HIDDEN; 449117395Skan 450132718Skan/* The merge function that just sums the counters. */ 451146895Skanextern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; 452117395Skan 453132718Skan/* The merge function to choose the most common value. */ 454146895Skanextern void __gcov_merge_single (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; 455117395Skan 456132718Skan/* The merge function to choose the most common difference between 457132718Skan consecutive values. */ 458146895Skanextern void __gcov_merge_delta (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; 459169689Skan 460169689Skan/* The profiler functions. */ 461169689Skanextern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned); 462169689Skanextern void __gcov_pow2_profiler (gcov_type *, gcov_type); 463169689Skanextern void __gcov_one_value_profiler (gcov_type *, gcov_type); 464169689Skan 465169689Skan#ifndef inhibit_libc 466169689Skan/* The wrappers around some library functions.. */ 467169689Skanextern pid_t __gcov_fork (void); 468169689Skanextern int __gcov_execl (const char *, const char *, ...) ATTRIBUTE_HIDDEN; 469169689Skanextern int __gcov_execlp (const char *, const char *, ...) ATTRIBUTE_HIDDEN; 470169689Skanextern int __gcov_execle (const char *, const char *, ...) ATTRIBUTE_HIDDEN; 471169689Skanextern int __gcov_execv (const char *, char *const []) ATTRIBUTE_HIDDEN; 472169689Skanextern int __gcov_execvp (const char *, char *const []) ATTRIBUTE_HIDDEN; 473169689Skanextern int __gcov_execve (const char *, char *const [], char *const []) 474169689Skan ATTRIBUTE_HIDDEN; 475169689Skan#endif 476169689Skan 477132718Skan#endif /* IN_LIBGCOV */ 478117395Skan 479132718Skan#if IN_LIBGCOV >= 0 480117395Skan 481132718Skan/* Optimum number of gcov_unsigned_t's read from or written to disk. */ 482132718Skan#define GCOV_BLOCK_SIZE (1 << 10) 483117395Skan 484132718SkanGCOV_LINKAGE struct gcov_var 485132718Skan{ 486132718Skan FILE *file; 487132718Skan gcov_position_t start; /* Position of first byte of block */ 488132718Skan unsigned offset; /* Read/write position within the block. */ 489132718Skan unsigned length; /* Read limit in the block. */ 490132718Skan unsigned overread; /* Number of words overread. */ 491132718Skan int error; /* < 0 overflow, > 0 disk error. */ 492132718Skan int mode; /* < 0 writing, > 0 reading */ 493132718Skan#if IN_LIBGCOV 494132718Skan /* Holds one block plus 4 bytes, thus all coverage reads & writes 495132718Skan fit within this buffer and we always can transfer GCOV_BLOCK_SIZE 496132718Skan to and from the disk. libgcov never backtracks and only writes 4 497132718Skan or 8 byte objects. */ 498132718Skan gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1]; 499132718Skan#else 500132718Skan int endian; /* Swap endianness. */ 501132718Skan /* Holds a variable length block, as the compiler can write 502132718Skan strings and needs to backtrack. */ 503132718Skan size_t alloc; 504132718Skan gcov_unsigned_t *buffer; 505132718Skan#endif 506146895Skan} gcov_var ATTRIBUTE_HIDDEN; 507117395Skan 508132718Skan/* Functions for reading and writing gcov files. In libgcov you can 509132718Skan open the file for reading then writing. Elsewhere you can open the 510132718Skan file either for reading or for writing. When reading a file you may 511132718Skan use the gcov_read_* functions, gcov_sync, gcov_position, & 512132718Skan gcov_error. When writing a file you may use the gcov_write 513132718Skan functions, gcov_seek & gcov_error. When a file is to be rewritten 514132718Skan you use the functions for reading, then gcov_rewrite then the 515132718Skan functions for writing. Your file may become corrupted if you break 516132718Skan these invariants. */ 517132718Skan#if IN_LIBGCOV 518146895SkanGCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN; 519132718Skan#else 520132718SkanGCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/); 521132718SkanGCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t); 522132718Skan#endif 523146895SkanGCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN; 524117395Skan 525132718Skan/* Available everywhere. */ 526132718Skanstatic gcov_position_t gcov_position (void); 527132718Skanstatic int gcov_is_error (void); 528117395Skan 529146895SkanGCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN; 530146895SkanGCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN; 531146895SkanGCOV_LINKAGE void gcov_read_summary (struct gcov_summary *) ATTRIBUTE_HIDDEN; 532117395Skan 533132718Skan#if IN_LIBGCOV 534132718Skan/* Available only in libgcov */ 535146895SkanGCOV_LINKAGE void gcov_write_counter (gcov_type) ATTRIBUTE_HIDDEN; 536146895SkanGCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t) 537146895Skan ATTRIBUTE_HIDDEN; 538132718SkanGCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/, 539146895Skan const struct gcov_summary *) 540146895Skan ATTRIBUTE_HIDDEN; 541132718Skanstatic void gcov_rewrite (void); 542146895SkanGCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN; 543132718Skan#else 544132718Skan/* Available outside libgcov */ 545132718SkanGCOV_LINKAGE const char *gcov_read_string (void); 546132718SkanGCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/, 547132718Skan gcov_unsigned_t /*length */); 548132718Skan#endif 549117395Skan 550132718Skan#if !IN_GCOV 551132718Skan/* Available outside gcov */ 552146895SkanGCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t) ATTRIBUTE_HIDDEN; 553132718Skan#endif 554117395Skan 555132718Skan#if !IN_GCOV && !IN_LIBGCOV 556132718Skan/* Available only in compiler */ 557132718SkanGCOV_LINKAGE void gcov_write_string (const char *); 558132718SkanGCOV_LINKAGE gcov_position_t gcov_write_tag (gcov_unsigned_t); 559132718SkanGCOV_LINKAGE void gcov_write_length (gcov_position_t /*position*/); 560132718Skan#endif 561117395Skan 562132718Skan#if IN_GCOV > 0 563132718Skan/* Available in gcov */ 564132718SkanGCOV_LINKAGE time_t gcov_time (void); 565132718Skan#endif 566117395Skan 567132718Skan/* Save the current position in the gcov file. */ 568117395Skan 569132718Skanstatic inline gcov_position_t 570132718Skangcov_position (void) 571132718Skan{ 572169689Skan gcc_assert (gcov_var.mode > 0); 573132718Skan return gcov_var.start + gcov_var.offset; 574132718Skan} 575117395Skan 576132718Skan/* Return nonzero if the error flag is set. */ 577117395Skan 578132718Skanstatic inline int 579132718Skangcov_is_error (void) 580132718Skan{ 581132718Skan return gcov_var.file ? gcov_var.error : 1; 582132718Skan} 583117395Skan 584132718Skan#if IN_LIBGCOV 585132718Skan/* Move to beginning of file and initialize for writing. */ 586117395Skan 587132718Skanstatic inline void 588132718Skangcov_rewrite (void) 589132718Skan{ 590169689Skan gcc_assert (gcov_var.mode > 0); 591132718Skan gcov_var.mode = -1; 592132718Skan gcov_var.start = 0; 593132718Skan gcov_var.offset = 0; 594132718Skan fseek (gcov_var.file, 0L, SEEK_SET); 595117395Skan} 596132718Skan#endif 597117395Skan 598132718Skan#endif /* IN_LIBGCOV >= 0 */ 599132718Skan 600132718Skan#endif /* GCC_GCOV_IO_H */ 601