libgcov-driver.c revision 1.1.1.6 1 1.1 mrg /* Routines required for instrumenting a program. */
2 1.1 mrg /* Compile this one with gcc. */
3 1.1.1.6 mrg /* Copyright (C) 1989-2017 Free Software Foundation, Inc.
4 1.1 mrg
5 1.1 mrg This file is part of GCC.
6 1.1 mrg
7 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
8 1.1 mrg the terms of the GNU General Public License as published by the Free
9 1.1 mrg Software Foundation; either version 3, or (at your option) any later
10 1.1 mrg version.
11 1.1 mrg
12 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 1.1 mrg for more details.
16 1.1 mrg
17 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
18 1.1 mrg permissions described in the GCC Runtime Library Exception, version
19 1.1 mrg 3.1, as published by the Free Software Foundation.
20 1.1 mrg
21 1.1 mrg You should have received a copy of the GNU General Public License and
22 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
23 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 1.1 mrg <http://www.gnu.org/licenses/>. */
25 1.1 mrg
26 1.1 mrg #include "libgcov.h"
27 1.1 mrg
28 1.1 mrg #if defined(inhibit_libc)
29 1.1 mrg /* If libc and its header files are not available, provide dummy functions. */
30 1.1 mrg
31 1.1 mrg #if defined(L_gcov)
32 1.1 mrg void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
33 1.1 mrg #endif
34 1.1 mrg
35 1.1 mrg #else /* inhibit_libc */
36 1.1 mrg
37 1.1 mrg #include <string.h>
38 1.1 mrg #if GCOV_LOCKED
39 1.1 mrg #include <fcntl.h>
40 1.1 mrg #include <errno.h>
41 1.1 mrg #include <sys/stat.h>
42 1.1 mrg #endif
43 1.1 mrg
44 1.1 mrg #ifdef L_gcov
45 1.1 mrg
46 1.1.1.4 mrg /* A utility function for outputting errors. */
47 1.1 mrg static int gcov_error (const char *, ...);
48 1.1 mrg
49 1.1.1.4 mrg #if !IN_GCOV_TOOL
50 1.1.1.4 mrg static void gcov_error_exit (void);
51 1.1.1.4 mrg #endif
52 1.1.1.4 mrg
53 1.1 mrg #include "gcov-io.c"
54 1.1 mrg
55 1.1 mrg struct gcov_fn_buffer
56 1.1 mrg {
57 1.1 mrg struct gcov_fn_buffer *next;
58 1.1 mrg unsigned fn_ix;
59 1.1 mrg struct gcov_fn_info info;
60 1.1 mrg /* note gcov_fn_info ends in a trailing array. */
61 1.1 mrg };
62 1.1 mrg
63 1.1 mrg struct gcov_summary_buffer
64 1.1 mrg {
65 1.1 mrg struct gcov_summary_buffer *next;
66 1.1 mrg struct gcov_summary summary;
67 1.1 mrg };
68 1.1 mrg
69 1.1 mrg /* A struct that bundles all the related information about the
70 1.1 mrg gcda filename. */
71 1.1 mrg
72 1.1 mrg struct gcov_filename
73 1.1 mrg {
74 1.1 mrg char *filename; /* filename buffer */
75 1.1 mrg size_t max_length; /* maximum filename length */
76 1.1 mrg int strip; /* leading chars to strip from filename */
77 1.1 mrg size_t prefix; /* chars to prepend to filename */
78 1.1 mrg };
79 1.1 mrg
80 1.1 mrg static struct gcov_fn_buffer *
81 1.1 mrg free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
82 1.1 mrg unsigned limit)
83 1.1 mrg {
84 1.1 mrg struct gcov_fn_buffer *next;
85 1.1 mrg unsigned ix, n_ctr = 0;
86 1.1 mrg
87 1.1 mrg if (!buffer)
88 1.1 mrg return 0;
89 1.1 mrg next = buffer->next;
90 1.1 mrg
91 1.1 mrg for (ix = 0; ix != limit; ix++)
92 1.1 mrg if (gi_ptr->merge[ix])
93 1.1 mrg free (buffer->info.ctrs[n_ctr++].values);
94 1.1 mrg free (buffer);
95 1.1 mrg return next;
96 1.1 mrg }
97 1.1 mrg
98 1.1 mrg static struct gcov_fn_buffer **
99 1.1 mrg buffer_fn_data (const char *filename, const struct gcov_info *gi_ptr,
100 1.1 mrg struct gcov_fn_buffer **end_ptr, unsigned fn_ix)
101 1.1 mrg {
102 1.1 mrg unsigned n_ctrs = 0, ix = 0;
103 1.1 mrg struct gcov_fn_buffer *fn_buffer;
104 1.1 mrg unsigned len;
105 1.1 mrg
106 1.1 mrg for (ix = GCOV_COUNTERS; ix--;)
107 1.1 mrg if (gi_ptr->merge[ix])
108 1.1 mrg n_ctrs++;
109 1.1 mrg
110 1.1 mrg len = sizeof (*fn_buffer) + sizeof (fn_buffer->info.ctrs[0]) * n_ctrs;
111 1.1 mrg fn_buffer = (struct gcov_fn_buffer *) xmalloc (len);
112 1.1 mrg
113 1.1 mrg if (!fn_buffer)
114 1.1 mrg goto fail;
115 1.1 mrg
116 1.1 mrg fn_buffer->next = 0;
117 1.1 mrg fn_buffer->fn_ix = fn_ix;
118 1.1 mrg fn_buffer->info.ident = gcov_read_unsigned ();
119 1.1 mrg fn_buffer->info.lineno_checksum = gcov_read_unsigned ();
120 1.1 mrg fn_buffer->info.cfg_checksum = gcov_read_unsigned ();
121 1.1 mrg
122 1.1 mrg for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++)
123 1.1 mrg {
124 1.1 mrg gcov_unsigned_t length;
125 1.1 mrg gcov_type *values;
126 1.1 mrg
127 1.1 mrg if (!gi_ptr->merge[ix])
128 1.1 mrg continue;
129 1.1 mrg
130 1.1 mrg if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix))
131 1.1 mrg {
132 1.1 mrg len = 0;
133 1.1 mrg goto fail;
134 1.1 mrg }
135 1.1 mrg
136 1.1 mrg length = GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
137 1.1 mrg len = length * sizeof (gcov_type);
138 1.1 mrg values = (gcov_type *) xmalloc (len);
139 1.1 mrg if (!values)
140 1.1 mrg goto fail;
141 1.1 mrg
142 1.1 mrg fn_buffer->info.ctrs[n_ctrs].num = length;
143 1.1 mrg fn_buffer->info.ctrs[n_ctrs].values = values;
144 1.1 mrg
145 1.1 mrg while (length--)
146 1.1 mrg *values++ = gcov_read_counter ();
147 1.1 mrg n_ctrs++;
148 1.1 mrg }
149 1.1 mrg
150 1.1 mrg *end_ptr = fn_buffer;
151 1.1 mrg return &fn_buffer->next;
152 1.1 mrg
153 1.1 mrg fail:
154 1.1 mrg gcov_error ("profiling:%s:Function %u %s %u \n", filename, fn_ix,
155 1.1 mrg len ? "cannot allocate" : "counter mismatch", len ? len : ix);
156 1.1 mrg
157 1.1 mrg return (struct gcov_fn_buffer **)free_fn_data (gi_ptr, fn_buffer, ix);
158 1.1 mrg }
159 1.1 mrg
160 1.1 mrg /* Add an unsigned value to the current crc */
161 1.1 mrg
162 1.1 mrg static gcov_unsigned_t
163 1.1 mrg crc32_unsigned (gcov_unsigned_t crc32, gcov_unsigned_t value)
164 1.1 mrg {
165 1.1 mrg unsigned ix;
166 1.1 mrg
167 1.1 mrg for (ix = 32; ix--; value <<= 1)
168 1.1 mrg {
169 1.1 mrg unsigned feedback;
170 1.1 mrg
171 1.1 mrg feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
172 1.1 mrg crc32 <<= 1;
173 1.1 mrg crc32 ^= feedback;
174 1.1 mrg }
175 1.1 mrg
176 1.1 mrg return crc32;
177 1.1 mrg }
178 1.1 mrg
179 1.1 mrg /* Check if VERSION of the info block PTR matches libgcov one.
180 1.1 mrg Return 1 on success, or zero in case of versions mismatch.
181 1.1 mrg If FILENAME is not NULL, its value used for reporting purposes
182 1.1 mrg instead of value from the info block. */
183 1.1 mrg
184 1.1 mrg static int
185 1.1 mrg gcov_version (struct gcov_info *ptr, gcov_unsigned_t version,
186 1.1 mrg const char *filename)
187 1.1 mrg {
188 1.1 mrg if (version != GCOV_VERSION)
189 1.1 mrg {
190 1.1 mrg char v[4], e[4];
191 1.1 mrg
192 1.1 mrg GCOV_UNSIGNED2STRING (v, version);
193 1.1 mrg GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
194 1.1 mrg
195 1.1 mrg gcov_error ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
196 1.1 mrg filename? filename : ptr->filename, e, v);
197 1.1 mrg return 0;
198 1.1 mrg }
199 1.1 mrg return 1;
200 1.1 mrg }
201 1.1 mrg
202 1.1 mrg /* Insert counter VALUE into HISTOGRAM. */
203 1.1 mrg
204 1.1 mrg static void
205 1.1 mrg gcov_histogram_insert(gcov_bucket_type *histogram, gcov_type value)
206 1.1 mrg {
207 1.1 mrg unsigned i;
208 1.1 mrg
209 1.1 mrg i = gcov_histo_index(value);
210 1.1 mrg histogram[i].num_counters++;
211 1.1 mrg histogram[i].cum_value += value;
212 1.1 mrg if (value < histogram[i].min_value)
213 1.1 mrg histogram[i].min_value = value;
214 1.1 mrg }
215 1.1 mrg
216 1.1 mrg /* Computes a histogram of the arc counters to place in the summary SUM. */
217 1.1 mrg
218 1.1 mrg static void
219 1.1 mrg gcov_compute_histogram (struct gcov_info *list, struct gcov_summary *sum)
220 1.1 mrg {
221 1.1 mrg struct gcov_info *gi_ptr;
222 1.1 mrg const struct gcov_fn_info *gfi_ptr;
223 1.1 mrg const struct gcov_ctr_info *ci_ptr;
224 1.1 mrg struct gcov_ctr_summary *cs_ptr;
225 1.1 mrg unsigned t_ix, f_ix, ctr_info_ix, ix;
226 1.1 mrg int h_ix;
227 1.1 mrg
228 1.1 mrg /* This currently only applies to arc counters. */
229 1.1 mrg t_ix = GCOV_COUNTER_ARCS;
230 1.1 mrg
231 1.1 mrg /* First check if there are any counts recorded for this counter. */
232 1.1 mrg cs_ptr = &(sum->ctrs[t_ix]);
233 1.1 mrg if (!cs_ptr->num)
234 1.1 mrg return;
235 1.1 mrg
236 1.1 mrg for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
237 1.1 mrg {
238 1.1 mrg cs_ptr->histogram[h_ix].num_counters = 0;
239 1.1 mrg cs_ptr->histogram[h_ix].min_value = cs_ptr->run_max;
240 1.1 mrg cs_ptr->histogram[h_ix].cum_value = 0;
241 1.1 mrg }
242 1.1 mrg
243 1.1 mrg /* Walk through all the per-object structures and record each of
244 1.1 mrg the count values in histogram. */
245 1.1 mrg for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
246 1.1 mrg {
247 1.1 mrg if (!gi_ptr->merge[t_ix])
248 1.1 mrg continue;
249 1.1 mrg
250 1.1 mrg /* Find the appropriate index into the gcov_ctr_info array
251 1.1 mrg for the counter we are currently working on based on the
252 1.1 mrg existence of the merge function pointer for this object. */
253 1.1 mrg for (ix = 0, ctr_info_ix = 0; ix < t_ix; ix++)
254 1.1 mrg {
255 1.1 mrg if (gi_ptr->merge[ix])
256 1.1 mrg ctr_info_ix++;
257 1.1 mrg }
258 1.1 mrg for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
259 1.1 mrg {
260 1.1 mrg gfi_ptr = gi_ptr->functions[f_ix];
261 1.1 mrg
262 1.1 mrg if (!gfi_ptr || gfi_ptr->key != gi_ptr)
263 1.1 mrg continue;
264 1.1 mrg
265 1.1 mrg ci_ptr = &gfi_ptr->ctrs[ctr_info_ix];
266 1.1 mrg for (ix = 0; ix < ci_ptr->num; ix++)
267 1.1 mrg gcov_histogram_insert (cs_ptr->histogram, ci_ptr->values[ix]);
268 1.1 mrg }
269 1.1 mrg }
270 1.1 mrg }
271 1.1 mrg
272 1.1 mrg /* buffer for the fn_data from another program. */
273 1.1 mrg static struct gcov_fn_buffer *fn_buffer;
274 1.1 mrg /* buffer for summary from other programs to be written out. */
275 1.1 mrg static struct gcov_summary_buffer *sum_buffer;
276 1.1 mrg
277 1.1 mrg /* This function computes the program level summary and the histo-gram.
278 1.1 mrg It computes and returns CRC32 and stored summary in THIS_PRG.
279 1.1 mrg Also determines the longest filename length of the info files. */
280 1.1 mrg
281 1.1 mrg #if !IN_GCOV_TOOL
282 1.1 mrg static
283 1.1 mrg #endif
284 1.1 mrg gcov_unsigned_t
285 1.1 mrg compute_summary (struct gcov_info *list, struct gcov_summary *this_prg,
286 1.1 mrg size_t *max_length)
287 1.1 mrg {
288 1.1 mrg struct gcov_info *gi_ptr;
289 1.1 mrg const struct gcov_fn_info *gfi_ptr;
290 1.1 mrg struct gcov_ctr_summary *cs_ptr;
291 1.1 mrg const struct gcov_ctr_info *ci_ptr;
292 1.1 mrg int f_ix;
293 1.1 mrg unsigned t_ix;
294 1.1 mrg gcov_unsigned_t c_num;
295 1.1 mrg gcov_unsigned_t crc32 = 0;
296 1.1 mrg
297 1.1 mrg /* Find the totals for this execution. */
298 1.1 mrg memset (this_prg, 0, sizeof (*this_prg));
299 1.1 mrg *max_length = 0;
300 1.1 mrg for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
301 1.1 mrg {
302 1.1 mrg size_t len = strlen (gi_ptr->filename);
303 1.1 mrg if (len > *max_length)
304 1.1 mrg *max_length = len;
305 1.1 mrg
306 1.1 mrg crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
307 1.1 mrg crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
308 1.1 mrg
309 1.1 mrg for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
310 1.1 mrg {
311 1.1 mrg gfi_ptr = gi_ptr->functions[f_ix];
312 1.1 mrg
313 1.1 mrg if (gfi_ptr && gfi_ptr->key != gi_ptr)
314 1.1 mrg gfi_ptr = 0;
315 1.1 mrg
316 1.1 mrg crc32 = crc32_unsigned (crc32, gfi_ptr ? gfi_ptr->cfg_checksum : 0);
317 1.1 mrg crc32 = crc32_unsigned (crc32,
318 1.1 mrg gfi_ptr ? gfi_ptr->lineno_checksum : 0);
319 1.1 mrg if (!gfi_ptr)
320 1.1 mrg continue;
321 1.1 mrg
322 1.1 mrg ci_ptr = gfi_ptr->ctrs;
323 1.1 mrg for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
324 1.1 mrg {
325 1.1 mrg if (!gi_ptr->merge[t_ix])
326 1.1 mrg continue;
327 1.1 mrg
328 1.1 mrg cs_ptr = &(this_prg->ctrs[t_ix]);
329 1.1 mrg cs_ptr->num += ci_ptr->num;
330 1.1 mrg crc32 = crc32_unsigned (crc32, ci_ptr->num);
331 1.1 mrg
332 1.1 mrg for (c_num = 0; c_num < ci_ptr->num; c_num++)
333 1.1 mrg {
334 1.1 mrg cs_ptr->sum_all += ci_ptr->values[c_num];
335 1.1 mrg if (cs_ptr->run_max < ci_ptr->values[c_num])
336 1.1 mrg cs_ptr->run_max = ci_ptr->values[c_num];
337 1.1 mrg }
338 1.1 mrg ci_ptr++;
339 1.1 mrg }
340 1.1 mrg }
341 1.1 mrg }
342 1.1 mrg gcov_compute_histogram (list, this_prg);
343 1.1 mrg return crc32;
344 1.1 mrg }
345 1.1 mrg
346 1.1 mrg /* Including system dependent components. */
347 1.1 mrg #include "libgcov-driver-system.c"
348 1.1 mrg
349 1.1 mrg /* This function merges counters in GI_PTR to an existing gcda file.
350 1.1 mrg Return 0 on success.
351 1.1 mrg Return -1 on error. In this case, caller will goto read_fatal. */
352 1.1 mrg
353 1.1 mrg static int
354 1.1 mrg merge_one_data (const char *filename,
355 1.1 mrg struct gcov_info *gi_ptr,
356 1.1 mrg struct gcov_summary *prg_p,
357 1.1 mrg struct gcov_summary *this_prg,
358 1.1 mrg gcov_position_t *summary_pos_p,
359 1.1 mrg gcov_position_t *eof_pos_p,
360 1.1 mrg gcov_unsigned_t crc32)
361 1.1 mrg {
362 1.1 mrg gcov_unsigned_t tag, length;
363 1.1 mrg unsigned t_ix;
364 1.1 mrg int f_ix;
365 1.1 mrg int error = 0;
366 1.1 mrg struct gcov_fn_buffer **fn_tail = &fn_buffer;
367 1.1 mrg struct gcov_summary_buffer **sum_tail = &sum_buffer;
368 1.1 mrg
369 1.1 mrg length = gcov_read_unsigned ();
370 1.1 mrg if (!gcov_version (gi_ptr, length, filename))
371 1.1 mrg return -1;
372 1.1 mrg
373 1.1 mrg length = gcov_read_unsigned ();
374 1.1 mrg if (length != gi_ptr->stamp)
375 1.1 mrg /* Read from a different compilation. Overwrite the file. */
376 1.1 mrg return 0;
377 1.1 mrg
378 1.1 mrg /* Look for program summary. */
379 1.1 mrg for (f_ix = 0;;)
380 1.1 mrg {
381 1.1 mrg struct gcov_summary tmp;
382 1.1 mrg
383 1.1 mrg *eof_pos_p = gcov_position ();
384 1.1 mrg tag = gcov_read_unsigned ();
385 1.1 mrg if (tag != GCOV_TAG_PROGRAM_SUMMARY)
386 1.1 mrg break;
387 1.1 mrg
388 1.1 mrg f_ix--;
389 1.1 mrg length = gcov_read_unsigned ();
390 1.1 mrg gcov_read_summary (&tmp);
391 1.1 mrg if ((error = gcov_is_error ()))
392 1.1 mrg goto read_error;
393 1.1 mrg if (*summary_pos_p)
394 1.1 mrg {
395 1.1 mrg /* Save all summaries after the one that will be
396 1.1 mrg merged into below. These will need to be rewritten
397 1.1 mrg as histogram merging may change the number of non-zero
398 1.1 mrg histogram entries that will be emitted, and thus the
399 1.1 mrg size of the merged summary. */
400 1.1 mrg (*sum_tail) = (struct gcov_summary_buffer *)
401 1.1 mrg xmalloc (sizeof(struct gcov_summary_buffer));
402 1.1 mrg (*sum_tail)->summary = tmp;
403 1.1 mrg (*sum_tail)->next = 0;
404 1.1 mrg sum_tail = &((*sum_tail)->next);
405 1.1 mrg goto next_summary;
406 1.1 mrg }
407 1.1 mrg if (tmp.checksum != crc32)
408 1.1 mrg goto next_summary;
409 1.1 mrg
410 1.1 mrg for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
411 1.1 mrg if (tmp.ctrs[t_ix].num != this_prg->ctrs[t_ix].num)
412 1.1 mrg goto next_summary;
413 1.1 mrg *prg_p = tmp;
414 1.1 mrg *summary_pos_p = *eof_pos_p;
415 1.1 mrg
416 1.1 mrg next_summary:;
417 1.1 mrg }
418 1.1 mrg
419 1.1 mrg /* Merge execution counts for each function. */
420 1.1 mrg for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions;
421 1.1 mrg f_ix++, tag = gcov_read_unsigned ())
422 1.1 mrg {
423 1.1 mrg const struct gcov_ctr_info *ci_ptr;
424 1.1 mrg const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
425 1.1 mrg
426 1.1 mrg if (tag != GCOV_TAG_FUNCTION)
427 1.1 mrg goto read_mismatch;
428 1.1 mrg
429 1.1 mrg length = gcov_read_unsigned ();
430 1.1 mrg if (!length)
431 1.1 mrg /* This function did not appear in the other program.
432 1.1 mrg We have nothing to merge. */
433 1.1 mrg continue;
434 1.1 mrg
435 1.1 mrg if (length != GCOV_TAG_FUNCTION_LENGTH)
436 1.1 mrg goto read_mismatch;
437 1.1 mrg
438 1.1 mrg if (!gfi_ptr || gfi_ptr->key != gi_ptr)
439 1.1 mrg {
440 1.1 mrg /* This function appears in the other program. We
441 1.1 mrg need to buffer the information in order to write
442 1.1 mrg it back out -- we'll be inserting data before
443 1.1 mrg this point, so cannot simply keep the data in the
444 1.1 mrg file. */
445 1.1 mrg fn_tail = buffer_fn_data (filename, gi_ptr, fn_tail, f_ix);
446 1.1 mrg if (!fn_tail)
447 1.1 mrg goto read_mismatch;
448 1.1 mrg continue;
449 1.1 mrg }
450 1.1 mrg
451 1.1 mrg length = gcov_read_unsigned ();
452 1.1 mrg if (length != gfi_ptr->ident)
453 1.1 mrg goto read_mismatch;
454 1.1 mrg
455 1.1 mrg length = gcov_read_unsigned ();
456 1.1 mrg if (length != gfi_ptr->lineno_checksum)
457 1.1 mrg goto read_mismatch;
458 1.1 mrg
459 1.1 mrg length = gcov_read_unsigned ();
460 1.1 mrg if (length != gfi_ptr->cfg_checksum)
461 1.1 mrg goto read_mismatch;
462 1.1 mrg
463 1.1 mrg ci_ptr = gfi_ptr->ctrs;
464 1.1 mrg for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
465 1.1 mrg {
466 1.1 mrg gcov_merge_fn merge = gi_ptr->merge[t_ix];
467 1.1 mrg
468 1.1 mrg if (!merge)
469 1.1 mrg continue;
470 1.1 mrg
471 1.1 mrg tag = gcov_read_unsigned ();
472 1.1 mrg length = gcov_read_unsigned ();
473 1.1 mrg if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
474 1.1 mrg || length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num))
475 1.1 mrg goto read_mismatch;
476 1.1 mrg (*merge) (ci_ptr->values, ci_ptr->num);
477 1.1 mrg ci_ptr++;
478 1.1 mrg }
479 1.1 mrg if ((error = gcov_is_error ()))
480 1.1 mrg goto read_error;
481 1.1 mrg }
482 1.1 mrg
483 1.1 mrg if (tag)
484 1.1 mrg {
485 1.1 mrg read_mismatch:;
486 1.1 mrg gcov_error ("profiling:%s:Merge mismatch for %s %u\n",
487 1.1 mrg filename, f_ix >= 0 ? "function" : "summary",
488 1.1 mrg f_ix < 0 ? -1 - f_ix : f_ix);
489 1.1 mrg return -1;
490 1.1 mrg }
491 1.1 mrg return 0;
492 1.1 mrg
493 1.1 mrg read_error:
494 1.1 mrg gcov_error ("profiling:%s:%s merging\n", filename,
495 1.1 mrg error < 0 ? "Overflow": "Error");
496 1.1 mrg return -1;
497 1.1 mrg }
498 1.1 mrg
499 1.1 mrg /* Write counters in GI_PTR and the summary in PRG to a gcda file. In
500 1.1 mrg the case of appending to an existing file, SUMMARY_POS will be non-zero.
501 1.1 mrg We will write the file starting from SUMMAY_POS. */
502 1.1 mrg
503 1.1 mrg static void
504 1.1 mrg write_one_data (const struct gcov_info *gi_ptr,
505 1.1 mrg const struct gcov_summary *prg_p,
506 1.1 mrg const gcov_position_t eof_pos,
507 1.1 mrg const gcov_position_t summary_pos)
508 1.1 mrg {
509 1.1 mrg unsigned f_ix;
510 1.1 mrg struct gcov_summary_buffer *next_sum_buffer;
511 1.1 mrg
512 1.1 mrg /* Write out the data. */
513 1.1 mrg if (!eof_pos)
514 1.1 mrg {
515 1.1 mrg gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
516 1.1 mrg gcov_write_unsigned (gi_ptr->stamp);
517 1.1 mrg }
518 1.1 mrg
519 1.1 mrg if (summary_pos)
520 1.1 mrg gcov_seek (summary_pos);
521 1.1 mrg
522 1.1 mrg /* Generate whole program statistics. */
523 1.1 mrg gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, prg_p);
524 1.1 mrg
525 1.1 mrg /* Rewrite all the summaries that were after the summary we merged
526 1.1 mrg into. This is necessary as the merged summary may have a different
527 1.1 mrg size due to the number of non-zero histogram entries changing after
528 1.1 mrg merging. */
529 1.1 mrg
530 1.1 mrg while (sum_buffer)
531 1.1 mrg {
532 1.1 mrg gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &sum_buffer->summary);
533 1.1 mrg next_sum_buffer = sum_buffer->next;
534 1.1 mrg free (sum_buffer);
535 1.1 mrg sum_buffer = next_sum_buffer;
536 1.1 mrg }
537 1.1 mrg
538 1.1 mrg /* Write execution counts for each function. */
539 1.1 mrg for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
540 1.1 mrg {
541 1.1 mrg unsigned buffered = 0;
542 1.1 mrg const struct gcov_fn_info *gfi_ptr;
543 1.1 mrg const struct gcov_ctr_info *ci_ptr;
544 1.1 mrg gcov_unsigned_t length;
545 1.1 mrg unsigned t_ix;
546 1.1 mrg
547 1.1 mrg if (fn_buffer && fn_buffer->fn_ix == f_ix)
548 1.1 mrg {
549 1.1 mrg /* Buffered data from another program. */
550 1.1 mrg buffered = 1;
551 1.1 mrg gfi_ptr = &fn_buffer->info;
552 1.1 mrg length = GCOV_TAG_FUNCTION_LENGTH;
553 1.1 mrg }
554 1.1 mrg else
555 1.1 mrg {
556 1.1 mrg gfi_ptr = gi_ptr->functions[f_ix];
557 1.1 mrg if (gfi_ptr && gfi_ptr->key == gi_ptr)
558 1.1 mrg length = GCOV_TAG_FUNCTION_LENGTH;
559 1.1 mrg else
560 1.1 mrg length = 0;
561 1.1 mrg }
562 1.1 mrg
563 1.1 mrg gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
564 1.1 mrg if (!length)
565 1.1 mrg continue;
566 1.1 mrg
567 1.1 mrg gcov_write_unsigned (gfi_ptr->ident);
568 1.1 mrg gcov_write_unsigned (gfi_ptr->lineno_checksum);
569 1.1 mrg gcov_write_unsigned (gfi_ptr->cfg_checksum);
570 1.1 mrg
571 1.1 mrg ci_ptr = gfi_ptr->ctrs;
572 1.1 mrg for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
573 1.1 mrg {
574 1.1 mrg gcov_unsigned_t n_counts;
575 1.1 mrg gcov_type *c_ptr;
576 1.1 mrg
577 1.1 mrg if (!gi_ptr->merge[t_ix])
578 1.1 mrg continue;
579 1.1 mrg
580 1.1 mrg n_counts = ci_ptr->num;
581 1.1 mrg gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
582 1.1 mrg GCOV_TAG_COUNTER_LENGTH (n_counts));
583 1.1 mrg c_ptr = ci_ptr->values;
584 1.1 mrg while (n_counts--)
585 1.1 mrg gcov_write_counter (*c_ptr++);
586 1.1 mrg ci_ptr++;
587 1.1 mrg }
588 1.1 mrg if (buffered)
589 1.1 mrg fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
590 1.1 mrg }
591 1.1 mrg
592 1.1 mrg gcov_write_unsigned (0);
593 1.1 mrg }
594 1.1 mrg
595 1.1 mrg /* Helper function for merging summary.
596 1.1 mrg Return -1 on error. Return 0 on success. */
597 1.1 mrg
598 1.1 mrg static int
599 1.1 mrg merge_summary (const char *filename, int run_counted,
600 1.1 mrg const struct gcov_info *gi_ptr, struct gcov_summary *prg,
601 1.1 mrg struct gcov_summary *this_prg, gcov_unsigned_t crc32,
602 1.1 mrg struct gcov_summary *all_prg __attribute__ ((unused)))
603 1.1 mrg {
604 1.1 mrg struct gcov_ctr_summary *cs_prg, *cs_tprg;
605 1.1 mrg unsigned t_ix;
606 1.1 mrg #if !GCOV_LOCKED
607 1.1 mrg /* summary for all instances of program. */
608 1.1 mrg struct gcov_ctr_summary *cs_all;
609 1.1 mrg #endif
610 1.1 mrg
611 1.1 mrg /* Merge the summaries. */
612 1.1 mrg for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
613 1.1 mrg {
614 1.1 mrg cs_prg = &(prg->ctrs[t_ix]);
615 1.1 mrg cs_tprg = &(this_prg->ctrs[t_ix]);
616 1.1 mrg
617 1.1 mrg if (gi_ptr->merge[t_ix])
618 1.1 mrg {
619 1.1 mrg int first = !cs_prg->runs;
620 1.1 mrg
621 1.1 mrg if (!run_counted)
622 1.1 mrg cs_prg->runs++;
623 1.1 mrg if (first)
624 1.1 mrg cs_prg->num = cs_tprg->num;
625 1.1 mrg cs_prg->sum_all += cs_tprg->sum_all;
626 1.1 mrg if (cs_prg->run_max < cs_tprg->run_max)
627 1.1 mrg cs_prg->run_max = cs_tprg->run_max;
628 1.1 mrg cs_prg->sum_max += cs_tprg->run_max;
629 1.1 mrg if (first)
630 1.1 mrg memcpy (cs_prg->histogram, cs_tprg->histogram,
631 1.1 mrg sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
632 1.1 mrg else
633 1.1 mrg gcov_histogram_merge (cs_prg->histogram, cs_tprg->histogram);
634 1.1 mrg }
635 1.1 mrg else if (cs_prg->runs)
636 1.1 mrg {
637 1.1 mrg gcov_error ("profiling:%s:Merge mismatch for summary.\n",
638 1.1 mrg filename);
639 1.1 mrg return -1;
640 1.1 mrg }
641 1.1 mrg #if !GCOV_LOCKED
642 1.1 mrg cs_all = &all_prg->ctrs[t_ix];
643 1.1 mrg if (!cs_all->runs && cs_prg->runs)
644 1.1 mrg {
645 1.1 mrg cs_all->num = cs_prg->num;
646 1.1 mrg cs_all->runs = cs_prg->runs;
647 1.1 mrg cs_all->sum_all = cs_prg->sum_all;
648 1.1 mrg cs_all->run_max = cs_prg->run_max;
649 1.1 mrg cs_all->sum_max = cs_prg->sum_max;
650 1.1 mrg }
651 1.1 mrg else if (!all_prg->checksum
652 1.1 mrg /* Don't compare the histograms, which may have slight
653 1.1 mrg variations depending on the order they were updated
654 1.1 mrg due to the truncating integer divides used in the
655 1.1 mrg merge. */
656 1.1 mrg && (cs_all->num != cs_prg->num
657 1.1 mrg || cs_all->runs != cs_prg->runs
658 1.1 mrg || cs_all->sum_all != cs_prg->sum_all
659 1.1 mrg || cs_all->run_max != cs_prg->run_max
660 1.1 mrg || cs_all->sum_max != cs_prg->sum_max))
661 1.1 mrg {
662 1.1 mrg gcov_error ("profiling:%s:Data file mismatch - some "
663 1.1 mrg "data files may have been concurrently "
664 1.1 mrg "updated without locking support\n", filename);
665 1.1 mrg all_prg->checksum = ~0u;
666 1.1 mrg }
667 1.1 mrg #endif
668 1.1 mrg }
669 1.1 mrg
670 1.1 mrg prg->checksum = crc32;
671 1.1 mrg
672 1.1 mrg return 0;
673 1.1 mrg }
674 1.1 mrg
675 1.1 mrg
676 1.1 mrg /* Sort N entries in VALUE_ARRAY in descending order.
677 1.1 mrg Each entry in VALUE_ARRAY has two values. The sorting
678 1.1 mrg is based on the second value. */
679 1.1 mrg
680 1.1 mrg GCOV_LINKAGE void
681 1.1 mrg gcov_sort_n_vals (gcov_type *value_array, int n)
682 1.1 mrg {
683 1.1 mrg int j, k;
684 1.1 mrg
685 1.1 mrg for (j = 2; j < n; j += 2)
686 1.1 mrg {
687 1.1 mrg gcov_type cur_ent[2];
688 1.1 mrg
689 1.1 mrg cur_ent[0] = value_array[j];
690 1.1 mrg cur_ent[1] = value_array[j + 1];
691 1.1 mrg k = j - 2;
692 1.1 mrg while (k >= 0 && value_array[k + 1] < cur_ent[1])
693 1.1 mrg {
694 1.1 mrg value_array[k + 2] = value_array[k];
695 1.1 mrg value_array[k + 3] = value_array[k+1];
696 1.1 mrg k -= 2;
697 1.1 mrg }
698 1.1 mrg value_array[k + 2] = cur_ent[0];
699 1.1 mrg value_array[k + 3] = cur_ent[1];
700 1.1 mrg }
701 1.1 mrg }
702 1.1 mrg
703 1.1 mrg /* Sort the profile counters for all indirect call sites. Counters
704 1.1 mrg for each call site are allocated in array COUNTERS. */
705 1.1 mrg
706 1.1 mrg static void
707 1.1 mrg gcov_sort_icall_topn_counter (const struct gcov_ctr_info *counters)
708 1.1 mrg {
709 1.1 mrg int i;
710 1.1 mrg gcov_type *values;
711 1.1 mrg int n = counters->num;
712 1.1 mrg
713 1.1 mrg gcc_assert (!(n % GCOV_ICALL_TOPN_NCOUNTS));
714 1.1 mrg values = counters->values;
715 1.1 mrg
716 1.1 mrg for (i = 0; i < n; i += GCOV_ICALL_TOPN_NCOUNTS)
717 1.1 mrg {
718 1.1 mrg gcov_type *value_array = &values[i + 1];
719 1.1 mrg gcov_sort_n_vals (value_array, GCOV_ICALL_TOPN_NCOUNTS - 1);
720 1.1 mrg }
721 1.1 mrg }
722 1.1 mrg
723 1.1 mrg /* Sort topn indirect_call profile counters in GI_PTR. */
724 1.1 mrg
725 1.1 mrg static void
726 1.1 mrg gcov_sort_topn_counter_arrays (const struct gcov_info *gi_ptr)
727 1.1 mrg {
728 1.1 mrg unsigned int i;
729 1.1 mrg int f_ix;
730 1.1 mrg const struct gcov_fn_info *gfi_ptr;
731 1.1 mrg const struct gcov_ctr_info *ci_ptr;
732 1.1 mrg
733 1.1 mrg if (!gi_ptr->merge[GCOV_COUNTER_ICALL_TOPNV])
734 1.1 mrg return;
735 1.1 mrg
736 1.1 mrg for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
737 1.1 mrg {
738 1.1 mrg gfi_ptr = gi_ptr->functions[f_ix];
739 1.1 mrg ci_ptr = gfi_ptr->ctrs;
740 1.1 mrg for (i = 0; i < GCOV_COUNTERS; i++)
741 1.1 mrg {
742 1.1 mrg if (!gi_ptr->merge[i])
743 1.1 mrg continue;
744 1.1 mrg if (i == GCOV_COUNTER_ICALL_TOPNV)
745 1.1 mrg {
746 1.1 mrg gcov_sort_icall_topn_counter (ci_ptr);
747 1.1 mrg break;
748 1.1 mrg }
749 1.1 mrg ci_ptr++;
750 1.1 mrg }
751 1.1 mrg }
752 1.1 mrg }
753 1.1 mrg
754 1.1 mrg /* Dump the coverage counts for one gcov_info object. We merge with existing
755 1.1 mrg counts when possible, to avoid growing the .da files ad infinitum. We use
756 1.1 mrg this program's checksum to make sure we only accumulate whole program
757 1.1 mrg statistics to the correct summary. An object file might be embedded
758 1.1 mrg in two separate programs, and we must keep the two program
759 1.1 mrg summaries separate. */
760 1.1 mrg
761 1.1 mrg static void
762 1.1 mrg dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
763 1.1 mrg unsigned run_counted,
764 1.1 mrg gcov_unsigned_t crc32, struct gcov_summary *all_prg,
765 1.1 mrg struct gcov_summary *this_prg)
766 1.1 mrg {
767 1.1 mrg struct gcov_summary prg; /* summary for this object over all program. */
768 1.1 mrg int error;
769 1.1 mrg gcov_unsigned_t tag;
770 1.1 mrg gcov_position_t summary_pos = 0;
771 1.1 mrg gcov_position_t eof_pos = 0;
772 1.1 mrg
773 1.1 mrg fn_buffer = 0;
774 1.1 mrg sum_buffer = 0;
775 1.1 mrg
776 1.1 mrg gcov_sort_topn_counter_arrays (gi_ptr);
777 1.1 mrg
778 1.1 mrg error = gcov_exit_open_gcda_file (gi_ptr, gf);
779 1.1 mrg if (error == -1)
780 1.1 mrg return;
781 1.1 mrg
782 1.1 mrg tag = gcov_read_unsigned ();
783 1.1 mrg if (tag)
784 1.1 mrg {
785 1.1 mrg /* Merge data from file. */
786 1.1 mrg if (tag != GCOV_DATA_MAGIC)
787 1.1 mrg {
788 1.1 mrg gcov_error ("profiling:%s:Not a gcov data file\n", gf->filename);
789 1.1 mrg goto read_fatal;
790 1.1 mrg }
791 1.1 mrg error = merge_one_data (gf->filename, gi_ptr, &prg, this_prg,
792 1.1 mrg &summary_pos, &eof_pos, crc32);
793 1.1 mrg if (error == -1)
794 1.1 mrg goto read_fatal;
795 1.1 mrg }
796 1.1 mrg
797 1.1 mrg gcov_rewrite ();
798 1.1 mrg
799 1.1 mrg if (!summary_pos)
800 1.1 mrg {
801 1.1 mrg memset (&prg, 0, sizeof (prg));
802 1.1 mrg summary_pos = eof_pos;
803 1.1 mrg }
804 1.1 mrg
805 1.1 mrg error = merge_summary (gf->filename, run_counted, gi_ptr, &prg, this_prg,
806 1.1 mrg crc32, all_prg);
807 1.1 mrg if (error == -1)
808 1.1 mrg goto read_fatal;
809 1.1 mrg
810 1.1 mrg write_one_data (gi_ptr, &prg, eof_pos, summary_pos);
811 1.1 mrg /* fall through */
812 1.1 mrg
813 1.1 mrg read_fatal:;
814 1.1 mrg while (fn_buffer)
815 1.1 mrg fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
816 1.1 mrg
817 1.1 mrg if ((error = gcov_close ()))
818 1.1 mrg gcov_error (error < 0 ?
819 1.1 mrg "profiling:%s:Overflow writing\n" :
820 1.1 mrg "profiling:%s:Error writing\n",
821 1.1 mrg gf->filename);
822 1.1 mrg }
823 1.1 mrg
824 1.1 mrg
825 1.1 mrg /* Dump all the coverage counts for the program. It first computes program
826 1.1 mrg summary and then traverses gcov_list list and dumps the gcov_info
827 1.1 mrg objects one by one. */
828 1.1 mrg
829 1.1 mrg #if !IN_GCOV_TOOL
830 1.1 mrg static
831 1.1 mrg #endif
832 1.1 mrg void
833 1.1 mrg gcov_do_dump (struct gcov_info *list, int run_counted)
834 1.1 mrg {
835 1.1 mrg struct gcov_info *gi_ptr;
836 1.1 mrg struct gcov_filename gf;
837 1.1 mrg gcov_unsigned_t crc32;
838 1.1 mrg struct gcov_summary all_prg;
839 1.1 mrg struct gcov_summary this_prg;
840 1.1 mrg
841 1.1 mrg crc32 = compute_summary (list, &this_prg, &gf.max_length);
842 1.1 mrg
843 1.1 mrg allocate_filename_struct (&gf);
844 1.1 mrg #if !GCOV_LOCKED
845 1.1 mrg memset (&all_prg, 0, sizeof (all_prg));
846 1.1 mrg #endif
847 1.1 mrg
848 1.1 mrg /* Now merge each file. */
849 1.1 mrg for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
850 1.1 mrg dump_one_gcov (gi_ptr, &gf, run_counted, crc32, &all_prg, &this_prg);
851 1.1 mrg
852 1.1 mrg free (gf.filename);
853 1.1 mrg }
854 1.1 mrg
855 1.1.1.2 mrg #if IN_GCOV_TOOL
856 1.1.1.2 mrg const char *
857 1.1.1.2 mrg __attribute__ ((unused))
858 1.1.1.2 mrg gcov_get_filename (struct gcov_info *list)
859 1.1.1.2 mrg {
860 1.1.1.2 mrg return list->filename;
861 1.1.1.2 mrg }
862 1.1.1.2 mrg #endif
863 1.1.1.2 mrg
864 1.1 mrg #if !IN_GCOV_TOOL
865 1.1 mrg void
866 1.1 mrg __gcov_dump_one (struct gcov_root *root)
867 1.1 mrg {
868 1.1 mrg if (root->dumped)
869 1.1 mrg return;
870 1.1 mrg
871 1.1 mrg gcov_do_dump (root->list, root->run_counted);
872 1.1 mrg
873 1.1 mrg root->dumped = 1;
874 1.1 mrg root->run_counted = 1;
875 1.1 mrg }
876 1.1 mrg
877 1.1 mrg /* Per-dynamic-object gcov state. */
878 1.1 mrg struct gcov_root __gcov_root;
879 1.1 mrg
880 1.1 mrg /* Exactly one of these will be live in the process image. */
881 1.1 mrg struct gcov_master __gcov_master =
882 1.1 mrg {GCOV_VERSION, 0};
883 1.1 mrg
884 1.1.1.4 mrg void
885 1.1.1.4 mrg __gcov_exit (void)
886 1.1 mrg {
887 1.1 mrg __gcov_dump_one (&__gcov_root);
888 1.1 mrg if (__gcov_root.next)
889 1.1 mrg __gcov_root.next->prev = __gcov_root.prev;
890 1.1 mrg if (__gcov_root.prev)
891 1.1 mrg __gcov_root.prev->next = __gcov_root.next;
892 1.1 mrg else
893 1.1 mrg __gcov_master.root = __gcov_root.next;
894 1.1.1.4 mrg
895 1.1.1.4 mrg gcov_error_exit ();
896 1.1 mrg }
897 1.1 mrg
898 1.1 mrg /* Add a new object file onto the bb chain. Invoked automatically
899 1.1 mrg when running an object file's global ctors. */
900 1.1 mrg
901 1.1 mrg void
902 1.1 mrg __gcov_init (struct gcov_info *info)
903 1.1 mrg {
904 1.1 mrg if (!info->version || !info->n_functions)
905 1.1 mrg return;
906 1.1 mrg if (gcov_version (info, info->version, 0))
907 1.1 mrg {
908 1.1 mrg if (!__gcov_root.list)
909 1.1 mrg {
910 1.1 mrg /* Add to master list and at exit function. */
911 1.1 mrg if (gcov_version (NULL, __gcov_master.version, "<master>"))
912 1.1 mrg {
913 1.1 mrg __gcov_root.next = __gcov_master.root;
914 1.1 mrg if (__gcov_master.root)
915 1.1 mrg __gcov_master.root->prev = &__gcov_root;
916 1.1 mrg __gcov_master.root = &__gcov_root;
917 1.1 mrg }
918 1.1 mrg }
919 1.1 mrg
920 1.1 mrg info->next = __gcov_root.list;
921 1.1 mrg __gcov_root.list = info;
922 1.1 mrg }
923 1.1 mrg }
924 1.1 mrg #endif /* !IN_GCOV_TOOL */
925 1.1 mrg #endif /* L_gcov */
926 1.1 mrg #endif /* inhibit_libc */
927