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