]>
Commit | Line | Data |
---|---|---|
4977bab6 | 1 | /* File format for coverage information |
ca29da43 NS |
2 | Copyright (C) 1996, 1997, 1998, 2000, 2002, |
3 | 2003 Free Software Foundation, Inc. | |
86144b75 | 4 | Contributed by Bob Manson <manson@cygnus.com>. |
4977bab6 | 5 | Completely remangled by Nathan Sidwell <nathan@codesourcery.com>. |
86144b75 | 6 | |
1322177d | 7 | This file is part of GCC. |
86144b75 | 8 | |
1322177d LB |
9 | GCC is free software; you can redistribute it and/or modify it under |
10 | the terms of the GNU General Public License as published by the Free | |
11 | Software Foundation; either version 2, or (at your option) any later | |
12 | version. | |
86144b75 | 13 | |
1322177d LB |
14 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
15 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 | for more details. | |
86144b75 DE |
18 | |
19 | You should have received a copy of the GNU General Public License | |
1322177d LB |
20 | along with GCC; see the file COPYING. If not, write to the Free |
21 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
22 | 02111-1307, USA. */ | |
86144b75 | 23 | |
77c915d8 DT |
24 | /* As a special exception, if you link this library with other files, |
25 | some of which are compiled with GCC, to produce an executable, | |
26 | this library does not by itself cause the resulting executable | |
27 | to be covered by the GNU General Public License. | |
28 | This exception does not however invalidate any other reasons why | |
29 | the executable file might be covered by the GNU General Public License. */ | |
30 | ||
4977bab6 ZW |
31 | /* Coverage information is held in two files. A basic block graph |
32 | file, which is generated by the compiler, and a counter file, which | |
33 | is generated by the program under test. Both files use a similar | |
34 | structure. We do not attempt to make these files backwards | |
35 | compatible with previous versions, as you only need coverage | |
36 | information when developing a program. We do hold version | |
37 | information, so that mismatches can be detected, and we use a | |
38 | format that allows tools to skip information they do not understand | |
39 | or are not interested in. | |
40 | ||
41 | Numbers are recorded in big endian unsigned binary form. Either in | |
42 | 32 or 64 bits. Strings are stored with a length count and NUL | |
43 | terminator, and 0 to 3 bytes of zero padding up to the next 4 byte | |
44 | boundary. Zero length and NULL strings are simply stored as a | |
45 | length of zero (they have no trailing NUL or padding). | |
46 | ||
47 | int32: byte3 byte2 byte1 byte0 | |
48 | int64: byte7 byte6 byte5 byte4 byte3 byte2 byte1 byte0 | |
49 | string: int32:0 | int32:length char* char:0 padding | |
50 | padding: | char:0 | char:0 char:0 | char:0 char:0 char:0 | |
51 | item: int32 | int64 | string | |
52 | ||
53 | The basic format of the files is | |
54 | ||
55 | file : int32:magic int32:version record* | |
56 | ||
57 | The magic ident is different for the bbg and the counter files. | |
58 | The version is the same for both files and is derived from gcc's | |
59 | version number. Although the ident and version are formally 32 bit | |
60 | numbers, they are derived from 4 character ASCII strings. The | |
61 | version number consists of the single character major version | |
62 | number, a two character minor version number (leading zero for | |
63 | versions less than 10), and a single character indicating the | |
64 | status of the release. That will be 'e' experimental, 'p' | |
65 | prerelease and 'r' for release. Because, by good fortune, these are | |
66 | in alphabetical order, string collating can be used to compare | |
67 | version strings, and because numbers are stored big endian, numeric | |
68 | comparison can be used when it is read as a 32 bit value. Be aware | |
69 | that the 'e' designation will (naturally) be unstable and might be | |
70 | incompatible with itself. For gcc 3.4 experimental, it would be | |
71 | '304e' (0x33303465). When the major version reaches 10, the letters | |
72 | A-Z will be used. Assuming minor increments releases every 6 | |
73 | months, we have to make a major increment every 50 years. Assuming | |
74 | major increments releases every 5 years, we're ok for the next 155 | |
75 | years -- good enough for me. | |
76 | ||
77 | A record has a tag, length and variable amount of data. | |
78 | ||
79 | record: header data | |
80 | header: int32:tag int32:length | |
81 | data: item* | |
82 | ||
83 | Records are not nested, but there is a record hierarchy. Tag | |
84 | numbers reflect this hierarchy. Tags are unique across bbg and da | |
85 | files. Some record types have a varying amount of data. The LENGTH | |
86 | is usually used to determine how much data. The tag value is split | |
87 | into 4 8-bit fields, one for each of four possible levels. The | |
88 | most significant is allocated first. Unused levels are zero. | |
89 | Active levels are odd-valued, so that the LSB of the level is one. | |
90 | A sub-level incorporates the values of its superlevels. This | |
91 | formatting allows you to determine the tag heirarchy, without | |
92 | understanding the tags themselves, and is similar to the standard | |
93 | section numbering used in technical documents. Level values | |
94 | [1..3f] are used for common tags, values [41..9f] for the graph | |
95 | file and [a1..ff] for the counter file. | |
96 | ||
97 | The basic block graph file contains the following records | |
796621e8 NS |
98 | bbg: unit function-graph* |
99 | unit: header int32:checksum string:source | |
4977bab6 | 100 | function-graph: announce_function basic_blocks {arcs | lines}* |
796621e8 NS |
101 | announce_function: header int32:ident int32:checksum |
102 | string:name string:source int32:lineno | |
4977bab6 ZW |
103 | basic_block: header int32:flags* |
104 | arcs: header int32:block_no arc* | |
105 | arc: int32:dest_block int32:flags | |
106 | lines: header int32:block_no line* | |
107 | int32:0 string:NULL | |
108 | line: int32:line_no | int32:0 string:filename | |
109 | ||
110 | The BASIC_BLOCK record holds per-bb flags. The number of blocks | |
111 | can be inferred from its data length. There is one ARCS record per | |
112 | basic block. The number of arcs from a bb is implicit from the | |
113 | data length. It enumerates the destination bb and per-arc flags. | |
114 | There is one LINES record per basic block, it enumerates the source | |
115 | lines which belong to that basic block. Source file names are | |
116 | introduced by a line number of 0, following lines are from the new | |
117 | source file. The initial source file for the function is NULL, but | |
118 | the current source file should be remembered from one LINES record | |
119 | to the next. The end of a block is indicated by an empty filename | |
120 | - this does not reset the current source file. Note there is no | |
121 | ordering of the ARCS and LINES records: they may be in any order, | |
122 | interleaved in any manner. The current filename follows the order | |
123 | the LINES records are stored in the file, *not* the ordering of the | |
124 | blocks they are for. | |
125 | ||
126 | The data file contains the following records. | |
796621e8 NS |
127 | da: {unit function-data* summary:object summary:program*}* |
128 | unit: header int32:checksum | |
4977bab6 | 129 | function-data: announce_function arc_counts |
796621e8 | 130 | announce_function: header int32:ident int32:checksum |
4977bab6 | 131 | arc_counts: header int64:count* |
cdb23767 NS |
132 | summary: int32:checksum {count-summary}GCOV_COUNTERS |
133 | count-summary: int32:num int32:runs int64:sum | |
134 | int64:max int64:sum_max | |
4977bab6 | 135 | |
27283c73 NS |
136 | The ANNOUNCE_FUNCTION record is the same as that in the BBG file, |
137 | but without the source location. | |
4977bab6 ZW |
138 | The ARC_COUNTS gives the counter values for those arcs that are |
139 | instrumented. The SUMMARY records give information about the whole | |
140 | object file and about the whole program. The checksum is used for | |
141 | whole program summaries, and disambiguates different programs which | |
142 | include the same instrumented object file. There may be several | |
143 | program summaries, each with a unique checksum. The object | |
144 | summary's checkum is zero. Note that the da file might contain | |
145 | information from several runs concatenated, or the data might be | |
146 | merged. | |
147 | ||
148 | This file is included by both the compiler, gcov tools and the | |
546d2adb NS |
149 | runtime support library libgcov. IN_LIBGCOV and IN_GCOV are used to |
150 | distinguish which case is which. If IN_LIBGCOV is non-zero, | |
151 | libgcov is being built. If IN_GCOV is non-zero, the gcov tools are | |
152 | being built. Otherwise the compiler is being built. IN_GCOV may be | |
153 | positive or negative. If positive, we are compiling a tool that | |
154 | requires additional functions (see the code for knowledge of what | |
155 | those functions are). */ | |
4977bab6 | 156 | |
88657302 RH |
157 | #ifndef GCC_GCOV_IO_H |
158 | #define GCC_GCOV_IO_H | |
86144b75 | 159 | |
546d2adb | 160 | #if IN_LIBGCOV |
4977bab6 ZW |
161 | #if LONG_TYPE_SIZE == GCOV_TYPE_SIZE |
162 | typedef long gcov_type; | |
163 | #else | |
164 | typedef long long gcov_type; | |
165 | #endif | |
cdb23767 NS |
166 | #if defined (TARGET_HAS_F_SETLKW) |
167 | #define GCOV_LOCKED 1 | |
168 | #else | |
169 | #define GCOV_LOCKED 0 | |
170 | #endif | |
546d2adb NS |
171 | #endif /* IN_LIBGCOV */ |
172 | #if IN_GCOV | |
173 | typedef HOST_WIDEST_INT gcov_type; | |
174 | #if IN_GCOV > 0 | |
175 | #include <sys/types.h> | |
176 | #endif | |
177 | #endif | |
4977bab6 | 178 | |
ca29da43 NS |
179 | /* In lib gcov we want function linkage to be static, so we do not |
180 | polute the global namespace. In the compiler we want it extern, so | |
181 | that they can be accessed from elsewhere. */ | |
182 | #if IN_LIBGCOV || IN_GCOV | |
183 | #define GCOV_LINKAGE static | |
184 | #else | |
185 | #ifndef GCOV_LINKAGE | |
186 | #define GCOV_LINKAGE extern | |
187 | #endif | |
188 | #endif | |
189 | ||
4977bab6 ZW |
190 | /* File suffixes. */ |
191 | #define GCOV_DATA_SUFFIX ".da" | |
192 | #define GCOV_GRAPH_SUFFIX ".bbg" | |
193 | ||
194 | /* File magic. */ | |
195 | #define GCOV_DATA_MAGIC 0x67636f76 /* "gcov" */ | |
196 | #define GCOV_GRAPH_MAGIC 0x67626267 /* "gbbg" */ | |
197 | ||
198 | /* gcov-iov.h is automatically generated by the makefile from | |
199 | version.c, it looks like | |
200 | #define GCOV_VERSION ((unsigned)0x89abcdef) | |
201 | */ | |
202 | #include "gcov-iov.h" | |
203 | ||
204 | /* The record tags. Values [1..3f] are for tags which may be in either | |
205 | file. Values [41..9f] for those in the bbg file and [a1..ff] for | |
206 | the data file. */ | |
207 | ||
208 | #define GCOV_TAG_FUNCTION ((unsigned)0x01000000) | |
209 | #define GCOV_TAG_BLOCKS ((unsigned)0x01410000) | |
210 | #define GCOV_TAG_ARCS ((unsigned)0x01430000) | |
211 | #define GCOV_TAG_LINES ((unsigned)0x01450000) | |
cdb23767 | 212 | #define GCOV_TAG_COUNTER_BASE ((unsigned)0x01a10000) /* First counter */ |
4977bab6 ZW |
213 | #define GCOV_TAG_OBJECT_SUMMARY ((unsigned)0xa1000000) |
214 | #define GCOV_TAG_PROGRAM_SUMMARY ((unsigned)0xa3000000) | |
cdb23767 NS |
215 | |
216 | /* Counters that are collected. */ | |
217 | #define GCOV_COUNTER_ARCS 0 /* Arc transitions. */ | |
218 | #define GCOV_COUNTERS 1 | |
219 | ||
220 | /* A list of human readable names of the counters */ | |
221 | #define GCOV_COUNTER_NAMES {"arcs"} | |
222 | ||
223 | /* Convert a counter index to a tag. */ | |
224 | #define GCOV_TAG_FOR_COUNTER(COUNT) \ | |
225 | (GCOV_TAG_COUNTER_BASE + ((COUNT) << 17)) | |
226 | /* Convert a tag to a counter. */ | |
227 | #define GCOV_COUNTER_FOR_TAG(TAG) \ | |
228 | (((TAG) - GCOV_TAG_COUNTER_BASE) >> 17) | |
229 | /* Check whether a tag is a counter tag. */ | |
230 | #define GCOV_TAG_IS_COUNTER(TAG) \ | |
231 | (!((TAG) & 0xFFFF) && GCOV_COUNTER_FOR_TAG (TAG) < GCOV_COUNTERS) | |
4977bab6 ZW |
232 | |
233 | /* The tag level mask has 1's in the position of the inner levels, & | |
234 | the lsb of the current level, and zero on the current and outer | |
235 | levels. */ | |
236 | #define GCOV_TAG_MASK(TAG) (((TAG) - 1) ^ (TAG)) | |
237 | ||
238 | /* Return nonzero if SUB is an immediate subtag of TAG. */ | |
239 | #define GCOV_TAG_IS_SUBTAG(TAG,SUB) \ | |
240 | (GCOV_TAG_MASK (TAG) >> 8 == GCOV_TAG_MASK (SUB) \ | |
241 | && !(((SUB) ^ (TAG)) & ~GCOV_TAG_MASK(TAG))) | |
242 | ||
243 | /* Return nonzero if SUB is at a sublevel to TAG. */ | |
244 | #define GCOV_TAG_IS_SUBLEVEL(TAG,SUB) \ | |
245 | (GCOV_TAG_MASK (TAG) > GCOV_TAG_MASK (SUB)) | |
246 | ||
247 | /* Basic block flags. */ | |
27283c73 | 248 | #define GCOV_BLOCK_UNEXPECTED (1 << 1) |
4977bab6 ZW |
249 | |
250 | /* Arc flags. */ | |
251 | #define GCOV_ARC_ON_TREE (1 << 0) | |
252 | #define GCOV_ARC_FAKE (1 << 1) | |
253 | #define GCOV_ARC_FALLTHROUGH (1 << 2) | |
254 | ||
255 | /* Structured records. */ | |
256 | ||
cdb23767 NS |
257 | /* Cumulative counter data. */ |
258 | struct gcov_ctr_summary | |
259 | { | |
260 | unsigned num; /* number of counters. */ | |
261 | unsigned runs; /* number of program runs */ | |
262 | gcov_type sum_all; /* sum of all counters accumulated. */ | |
263 | gcov_type run_max; /* maximum value on a single run. */ | |
264 | gcov_type sum_max; /* sum of individual run max values. */ | |
265 | }; | |
266 | ||
4977bab6 ZW |
267 | /* Object & program summary record. */ |
268 | struct gcov_summary | |
86144b75 | 269 | { |
4977bab6 | 270 | unsigned checksum; /* checksum of program */ |
cdb23767 | 271 | struct gcov_ctr_summary ctrs[GCOV_COUNTERS]; |
4977bab6 ZW |
272 | }; |
273 | ||
4977bab6 ZW |
274 | /* Structures embedded in coveraged program. The structures generated |
275 | by write_profile must match these. */ | |
276 | ||
546d2adb | 277 | #if IN_LIBGCOV |
cdb23767 NS |
278 | /* Information about a single function. This uses the trailing array |
279 | idiom. The number of counters is determined from the counter_mask | |
280 | in gcov_info. We hold an array of function info, so have to | |
281 | explicitly calculate the correct array stride. */ | |
282 | struct gcov_fn_info | |
cb9e4555 | 283 | { |
796621e8 | 284 | unsigned ident; /* unique ident of function */ |
cdb23767 NS |
285 | unsigned checksum; /* function checksum */ |
286 | unsigned n_ctrs[0]; /* instrumented counters */ | |
cb9e4555 ZD |
287 | }; |
288 | ||
cdb23767 NS |
289 | /* Information about counters. */ |
290 | struct gcov_ctr_info | |
25c3a4ef | 291 | { |
cdb23767 NS |
292 | unsigned num; /* number of counters. */ |
293 | gcov_type *values; /* their values. */ | |
4977bab6 | 294 | }; |
25c3a4ef | 295 | |
4977bab6 ZW |
296 | /* Information about a single object file. */ |
297 | struct gcov_info | |
86144b75 | 298 | { |
4977bab6 ZW |
299 | unsigned long version; /* expected version number */ |
300 | struct gcov_info *next; /* link to next, used by libgcc */ | |
301 | ||
302 | const char *filename; /* output file name */ | |
4977bab6 | 303 | |
4977bab6 | 304 | unsigned n_functions; /* number of functions */ |
cdb23767 | 305 | const struct gcov_fn_info *functions; /* table of functions */ |
4977bab6 | 306 | |
cdb23767 NS |
307 | unsigned ctr_mask; /* mask of counters instrumented. */ |
308 | struct gcov_ctr_info counts[0]; /* count data. The number of bits | |
309 | set in the ctr_mask field | |
310 | determines how big this array | |
311 | is. */ | |
4977bab6 ZW |
312 | }; |
313 | ||
314 | /* Register a new object file module. */ | |
315 | extern void __gcov_init (struct gcov_info *); | |
316 | ||
317 | /* Called before fork, to avoid double counting. */ | |
318 | extern void __gcov_flush (void); | |
319 | ||
546d2adb NS |
320 | #endif /* IN_LIBGCOV */ |
321 | ||
322 | /* Because small reads and writes, interspersed with seeks cause lots | |
323 | of disk activity, we buffer the entire count files. */ | |
324 | ||
ca29da43 | 325 | GCOV_LINKAGE struct gcov_var |
94de45d9 NS |
326 | { |
327 | FILE *file; | |
328 | size_t position; | |
329 | size_t length; | |
330 | size_t alloc; | |
331 | unsigned modified; | |
332 | int error; | |
333 | unsigned char *buffer; | |
334 | } gcov_var; | |
4977bab6 ZW |
335 | |
336 | /* Functions for reading and writing gcov files. */ | |
ca29da43 NS |
337 | GCOV_LINKAGE int gcov_open (const char */*name*/, int /*truncate*/); |
338 | GCOV_LINKAGE int gcov_close (void); | |
546d2adb | 339 | #if !IN_GCOV |
ca29da43 NS |
340 | GCOV_LINKAGE unsigned char *gcov_write_bytes (unsigned); |
341 | GCOV_LINKAGE void gcov_write_unsigned (unsigned); | |
546d2adb | 342 | #if IN_LIBGCOV |
ca29da43 | 343 | GCOV_LINKAGE void gcov_write_counter (gcov_type); |
796621e8 | 344 | #else |
ca29da43 | 345 | GCOV_LINKAGE void gcov_write_string (const char *); |
796621e8 | 346 | #endif |
ca29da43 NS |
347 | GCOV_LINKAGE unsigned long gcov_write_tag (unsigned); |
348 | GCOV_LINKAGE void gcov_write_length (unsigned long /*position*/); | |
546d2adb | 349 | #if IN_LIBGCOV |
ca29da43 | 350 | GCOV_LINKAGE void gcov_write_summary (unsigned, const struct gcov_summary *); |
546d2adb NS |
351 | #endif |
352 | #endif /* !IN_GCOV */ | |
ca29da43 NS |
353 | GCOV_LINKAGE const unsigned char *gcov_read_bytes (unsigned); |
354 | GCOV_LINKAGE unsigned gcov_read_unsigned (void); | |
355 | GCOV_LINKAGE gcov_type gcov_read_counter (void); | |
796621e8 | 356 | #if !IN_LIBGCOV |
ca29da43 | 357 | GCOV_LINKAGE const char *gcov_read_string (void); |
796621e8 | 358 | #endif |
ca29da43 | 359 | GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *); |
94de45d9 NS |
360 | static unsigned long gcov_position (void); |
361 | static void gcov_seek (unsigned long /*base*/, unsigned /*length */); | |
546d2adb | 362 | static unsigned long gcov_seek_end (void); |
94de45d9 NS |
363 | static int gcov_is_eof (void); |
364 | static int gcov_is_error (void); | |
546d2adb | 365 | #if IN_GCOV > 0 |
ca29da43 | 366 | GCOV_LINKAGE time_t gcov_time (void); |
94de45d9 | 367 | #endif |
b7c9bf28 | 368 | |
546d2adb | 369 | /* Save the current position in the gcov file. */ |
b7c9bf28 | 370 | |
546d2adb | 371 | static inline unsigned long |
94de45d9 | 372 | gcov_position (void) |
ec4a0419 | 373 | { |
94de45d9 | 374 | return gcov_var.position; |
ec4a0419 ZD |
375 | } |
376 | ||
546d2adb NS |
377 | /* Reset to a known position. BASE should have been obtained from |
378 | gcov_save_position, LENGTH should be a record length, or zero. */ | |
ec4a0419 | 379 | |
94de45d9 NS |
380 | static inline void |
381 | gcov_seek (unsigned long base, unsigned length) | |
546d2adb | 382 | { |
94de45d9 NS |
383 | if (gcov_var.buffer) |
384 | { | |
385 | base += length; | |
386 | if (gcov_var.length < base) | |
387 | { | |
388 | gcov_var.error = 1; | |
389 | base = gcov_var.length; | |
390 | } | |
391 | gcov_var.position = base; | |
392 | } | |
ec4a0419 ZD |
393 | } |
394 | ||
546d2adb | 395 | /* Move to the end of the gcov file. */ |
ec4a0419 | 396 | |
546d2adb NS |
397 | static inline unsigned long |
398 | gcov_seek_end () | |
ec4a0419 | 399 | { |
94de45d9 NS |
400 | gcov_var.position = gcov_var.length; |
401 | return gcov_var.position; | |
ec4a0419 ZD |
402 | } |
403 | ||
546d2adb NS |
404 | /* Tests whether we have reached end of .da file. */ |
405 | ||
406 | static inline int | |
94de45d9 | 407 | gcov_is_eof () |
ec4a0419 | 408 | { |
94de45d9 | 409 | return gcov_var.position == gcov_var.length; |
ec4a0419 ZD |
410 | } |
411 | ||
546d2adb NS |
412 | /* Return non-zero if the error flag is set. */ |
413 | ||
414 | static inline int | |
94de45d9 | 415 | gcov_is_error () |
ec4a0419 | 416 | { |
94de45d9 | 417 | return gcov_var.file ? gcov_var.error : 1; |
ec4a0419 ZD |
418 | } |
419 | ||
4977bab6 | 420 | #endif /* GCC_GCOV_IO_H */ |