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