##// END OF EJS Templates
Increased libgcov gcda buffer to avoid file splitting
jeandet -
r388:01d5c5b53213 No PWD scrub with... draft
parent child
Show More
@@ -1,2 +1,2
1 3081d1f9bb20b2b64a192585337a292a9804e0c5 LFR_basic-parameters
1 3081d1f9bb20b2b64a192585337a292a9804e0c5 LFR_basic-parameters
2 042275d1388a0f360073a0d85bf50d128f4b8cfc header/lfr_common_headers
2 7053a75ef0a55a40e950a8302065856f3bd06a26 header/lfr_common_headers
@@ -1,38 +1,41
1 #!/usr/bin/env python3
1 #!/usr/bin/env python3
2
2
3 __author__ = "Alexis Jeandet"
3 __author__ = "Alexis Jeandet"
4 __copyright__ = "Copyright 2018, Laboratory of Plasma Physics"
4 __copyright__ = "Copyright 2018, Laboratory of Plasma Physics"
5 __credits__ = []
5 __credits__ = []
6 __license__ = "GPLv2"
6 __license__ = "GPLv2"
7 __version__ = "1.0.0"
7 __version__ = "1.0.0"
8 __maintainer__ = "Alexis Jeandet"
8 __maintainer__ = "Alexis Jeandet"
9 __email__ = "alexis.jeandet@member.fsf.org"
9 __email__ = "alexis.jeandet@member.fsf.org"
10 __status__ = "Development"
10 __status__ = "Development"
11
11
12 import time
12 import time
13 import sys
13 import sys
14 import os
14 import os
15 import serial
15 import serial
16 import argparse
16 import argparse
17 from datetime import datetime
17 from datetime import datetime
18
18
19 parser = argparse.ArgumentParser()
19 parser = argparse.ArgumentParser()
20 parser.add_argument("-f", "--gcov-file", help="Gcov output file generated by record_lfr_console.py")
20 parser.add_argument("-f", "--gcov-file", help="Gcov output file generated by record_lfr_console.py")
21 args = parser.parse_args()
21 args = parser.parse_args()
22
22
23
23
24
24
25 def main():
25 def main():
26 with open(args.gcov_file,'r') as gcov:
26 with open(args.gcov_file,'r') as gcov:
27 files = []
27 for line in gcov.readlines():
28 for line in gcov.readlines():
28 head,dest_file,data = line.split(',')
29 head,dest_file,data = line.split(',')
29 if head == '_GCOV_':
30 if dest_file not in files:
30 print(f"Writing {dest_file}\n")
31 files.append(dest_file)
31 with open(dest_file,'wb') as gcda_file:
32 if head == '_GCOV_':
32 gcda_file.write(bytes([int(''.join(value),16) for value in zip(data[::2],data[1::2]) ]))
33 print(f"Writing {dest_file}\n")
33 else:
34 with open(dest_file,'wb') as gcda_file:
34 raise
35 gcda_file.write(bytes([int(''.join(value),16) for value in zip(data[::2],data[1::2]) ]))
36 else:
37 raise
35
38
36
39
37 if __name__ == "__main__":
40 if __name__ == "__main__":
38 main()
41 main()
@@ -1,820 +1,488
1 /* Test for GCC >= 3.4.4 && <= 4.4.6 */
1 /* Test for GCC >= 3.4.4 && <= 4.4.6 */
2 //#if ( ( __GNUC__ > 3 ) || \
2 //#if ( ( __GNUC__ > 3 ) || \
3 // ( __GNUC__ == 3 && __GNUC_MINOR__ > 4 )|| \
3 // ( __GNUC__ == 3 && __GNUC_MINOR__ > 4 )|| \
4 // ( __GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ >= 4 ) ) && \
4 // ( __GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ >= 4 ) ) && \
5 // ( ( __GNUC__ < 4 ) || \
5 // ( ( __GNUC__ < 4 ) || \
6 // ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 )|| \
6 // ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 )|| \
7 // ( __GNUC__ == 4 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ <= 6 ) )
7 // ( __GNUC__ == 4 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ <= 6 ) )
8 /*
8 /*
9 * =====================================================================================
9 * =====================================================================================
10 *
10 *
11 * Filename: gcov-io.c
11 * Filename: gcov-io.c
12 *
12 *
13 * Description: This is the I/O file for embedded systems
13 * Description: This is the I/O file for embedded systems
14 *
14 *
15 * Version: 1.0
15 * Version: 1.0
16 * Created: 03/04/08 09:51:59
16 * Created: 03/04/08 09:51:59
17 * Revision: none
17 * Revision: none
18 * Compiler: gcc
18 * Compiler: gcc
19 *
19 *
20 * Author: Aitor Viana Sanchez (avs), aitor.viana.sanchez@esa.int
20 * Author: Aitor Viana Sanchez (avs), aitor.viana.sanchez@esa.int
21 * Company: European Space Agency (ESA-ESTEC)
21 * Company: European Space Agency (ESA-ESTEC)
22 *
22 *
23 * =====================================================================================
23 * =====================================================================================
24 */
24 */
25
25
26 /* File format for coverage information
26 /* File format for coverage information
27 Copyright (C) 1996, 1997, 1998, 2000, 2002,
27 Copyright (C) 1996, 1997, 1998, 2000, 2002,
28 2003 Free Software Foundation, Inc.
28 2003 Free Software Foundation, Inc.
29 Contributed by Bob Manson <manson@cygnus.com>.
29 Contributed by Bob Manson <manson@cygnus.com>.
30 Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
30 Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
31
31
32 This file is part of GCC.
32 This file is part of GCC.
33
33
34 GCC is free software; you can redistribute it and/or modify it under
34 GCC is free software; you can redistribute it and/or modify it under
35 the terms of the GNU General Public License as published by the Free
35 the terms of the GNU General Public License as published by the Free
36 Software Foundation; either version 2, or (at your option) any later
36 Software Foundation; either version 2, or (at your option) any later
37 version.
37 version.
38
38
39 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
39 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
40 WARRANTY; without even the implied warranty of MERCHANTABILITY or
40 WARRANTY; without even the implied warranty of MERCHANTABILITY or
41 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
41 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
42 for more details.
42 for more details.
43
43
44 You should have received a copy of the GNU General Public License
44 You should have received a copy of the GNU General Public License
45 along with GCC; see the file COPYING. If not, write to the Free
45 along with GCC; see the file COPYING. If not, write to the Free
46 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
46 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
47 02111-1307, USA. */
47 02111-1307, USA. */
48
48
49 #include <stdio.h>
49 #include <stdio.h>
50 #include <stdlib.h> /* for atexit() */
50 #include <stdlib.h> /* for atexit() */
51 #include <string.h>
51 #include <string.h>
52 #include "gcov-io.h"
52 #include "gcov-io.h"
53
53
54 /* Routines declared in gcov-io.h. This file should be #included by
54 /* Routines declared in gcov-io.h. This file should be #included by
55 another source file, after having #included gcov-io.h. */
55 another source file, after having #included gcov-io.h. */
56
56
57
57
58 /* This function shall be defined somewhere else */
58 /* This function shall be defined somewhere else */
59 //int send_data(unsigned char * buffer, unsigned int size);
59 //int send_data(unsigned char * buffer, unsigned int size);
60
60
61 /*-----------------------------------------------------------------------------
61 /*-----------------------------------------------------------------------------
62 * PRIVATE INTERFACE
62 * PRIVATE INTERFACE
63 *-----------------------------------------------------------------------------*/
63 *-----------------------------------------------------------------------------*/
64
64
65 static void gcov_write_block (unsigned);
65 static void gcov_write_block (unsigned);
66 static gcov_unsigned_t *gcov_write_words (unsigned);
66 static gcov_unsigned_t *gcov_write_words (unsigned);
67 GCOV_LINKAGE int gcov_send (void);
67 GCOV_LINKAGE int gcov_send (void);
68 GCOV_LINKAGE int gcov_close(void);
68 GCOV_LINKAGE int gcov_close(void);
69 //static const gcov_unsigned_t *gcov_read_words (unsigned);
70
69
71 extern struct gcov_info * gcov_list;
70 extern struct gcov_info * gcov_list;
72 extern gcov_unsigned_t gcov_crc32;
71 extern gcov_unsigned_t gcov_crc32;
73
72
74 int dev_id = 0;
73 int dev_id = 0;
75
74
76 /*
75 /*
77 * === FUNCTION ======================================================================
76 * === FUNCTION ======================================================================
78 * Name: from_file
77 * Name: from_file
79 * Description: This function just return the given parameter
78 * Description: This function just return the given parameter
80 * =====================================================================================
79 * =====================================================================================
81 */
80 */
82 static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
81 static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
83 {
82 {
84 return value;
83 return value;
85 }
84 }
86
85
87 /*
86 /*
88 * === FUNCTION ======================================================================
87 * === FUNCTION ======================================================================
89 * Name: gcov_version
88 * Name: gcov_version
90 * Description: This function returns TRUE (1) if the gcov version is the
89 * Description: This function returns TRUE (1) if the gcov version is the
91 * version expected. The function returns FALSE (0) in any other case.
90 * version expected. The function returns FALSE (0) in any other case.
92 * =====================================================================================
91 * =====================================================================================
93 */
92 */
94 static int gcov_version (struct gcov_info *ptr, gcov_unsigned_t version)
93 static int gcov_version (struct gcov_info *ptr, gcov_unsigned_t version)
95 {
94 {
96 if (version != GCOV_VERSION)
95 if (version != GCOV_VERSION)
97 {
96 {
98 char v[4], e[4];
97 char v[4], e[4];
99
98
100 GCOV_UNSIGNED2STRING (v, version);
99 GCOV_UNSIGNED2STRING (v, version);
101 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
100 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
102
101
103 printf ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
102 printf ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
104 ptr->filename, e, v);
103 ptr->filename, e, v);
105
104
106 return 0;
105 return 0;
107 }
106 }
108 return 1;
107 return 1;
109 }
108 }
110
109
111
110
112 /*-----------------------------------------------------------------------------
111 /*-----------------------------------------------------------------------------
113 * PUBLIC INTERFACE
112 * PUBLIC INTERFACE
114 *-----------------------------------------------------------------------------*/
113 *-----------------------------------------------------------------------------*/
115
114
116 /* Dump the coverage counts. We merge with existing counts when
115 /* Dump the coverage counts. We merge with existing counts when
117 possible, to avoid growing the .da files ad infinitum. We use this
116 possible, to avoid growing the .da files ad infinitum. We use this
118 program's checksum to make sure we only accumulate whole program
117 program's checksum to make sure we only accumulate whole program
119 statistics to the correct summary. An object file might be embedded
118 statistics to the correct summary. An object file might be embedded
120 in two separate programs, and we must keep the two program
119 in two separate programs, and we must keep the two program
121 summaries separate. */
120 summaries separate. */
122
121
123 /*
122 /*
124 * === FUNCTION ======================================================================
123 * === FUNCTION ======================================================================
125 * Name: gcov_exit
124 * Name: gcov_exit
126 * Description: This function dumps the coverage couns. The merging with
125 * Description: This function dumps the coverage couns. The merging with
127 * existing counts is not done in embedded systems.
126 * existing counts is not done in embedded systems.
128 * =====================================================================================
127 * =====================================================================================
129 */
128 */
130 void gcov_exit (void)
129 void gcov_exit (void)
131 {
130 {
132 struct gcov_info *gi_ptr;
131 struct gcov_info *gi_ptr;
133 struct gcov_summary this_program;
132 struct gcov_summary this_program;
134 struct gcov_summary all;
133 struct gcov_summary all;
135 struct gcov_ctr_summary *cs_ptr;
134 struct gcov_ctr_summary *cs_ptr;
136 const struct gcov_ctr_info *ci_ptr;
135 const struct gcov_ctr_info *ci_ptr;
137 unsigned t_ix;
136 unsigned t_ix;
138 gcov_unsigned_t c_num;
137 gcov_unsigned_t c_num;
139 unsigned long coreId = 0;
138 unsigned long coreId = 0;
140
139
141 /* retrieve the id of the CPU the program is running on */
140 /* retrieve the id of the CPU the program is running on */
142 #ifdef LEON3
141 #ifdef LEON3
143 __asm__ __volatile__("rd %%asr17,%0\n\t"
142 __asm__ __volatile__("rd %%asr17,%0\n\t"
144 "srl %0,28,%0" :
143 "srl %0,28,%0" :
145 "=&r" (coreId) : );
144 "=&r" (coreId) : );
146 #endif
145 #endif
147
146
148 printf("_GCOVEXIT_BEGIN_,core%d\n", coreId); /* see also _GCOVEXIT_END_ */
147 printf("_GCOVEXIT_BEGIN_,core%d\n", coreId); /* see also _GCOVEXIT_END_ */
149
148
150 if(gcov_list == (void*)0x0)
149 if(gcov_list == (void*)0x0)
151 printf("%s: gcov_list == NULL\n", __func__);
150 printf("%s: gcov_list == NULL\n", __func__);
152
151
153 memset (&all, 0, sizeof (all));
152 memset (&all, 0, sizeof (all));
154 /* Find the totals for this execution. */
153 /* Find the totals for this execution. */
155 memset (&this_program, 0, sizeof (this_program));
154 memset (&this_program, 0, sizeof (this_program));
156 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
155 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
157 {
156 {
158
157
159 ci_ptr = gi_ptr->counts;
158 ci_ptr = gi_ptr->counts;
160 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
159 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
161 {
160 {
162 if (!((1 << t_ix) & gi_ptr->ctr_mask))
161 if (!((1 << t_ix) & gi_ptr->ctr_mask))
163 continue;
162 continue;
164
163
165 cs_ptr = &this_program.ctrs[t_ix];
164 cs_ptr = &this_program.ctrs[t_ix];
166 cs_ptr->num += ci_ptr->num;
165 cs_ptr->num += ci_ptr->num;
167 for (c_num = 0; c_num < ci_ptr->num; c_num++)
166 for (c_num = 0; c_num < ci_ptr->num; c_num++)
168 {
167 {
169 cs_ptr->sum_all += ci_ptr->values[c_num];
168 cs_ptr->sum_all += ci_ptr->values[c_num];
170 if (cs_ptr->run_max < ci_ptr->values[c_num])
169 if (cs_ptr->run_max < ci_ptr->values[c_num])
171 cs_ptr->run_max = ci_ptr->values[c_num];
170 cs_ptr->run_max = ci_ptr->values[c_num];
172 }
171 }
173 ci_ptr++;
172 ci_ptr++;
174 }
173 }
175 }
174 }
176 /* Now merge each file. */
175 /* Now merge each file. */
177 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
176 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
178 {
177 {
179 // struct gcov_summary this_object, object;
178
180 // struct gcov_ctr_summary *cs_obj, *cs_tobj, *cs_prg, *cs_tprg, *cs_all;
181 // int error = 0;
182 // gcov_unsigned_t tag, length;
183 // gcov_position_t summary_pos = 0;
184 struct gcov_summary program;
179 struct gcov_summary program;
185 gcov_type *values[GCOV_COUNTERS];
180 gcov_type *values[GCOV_COUNTERS];
186 const struct gcov_fn_info *fi_ptr;
181 const struct gcov_fn_info *fi_ptr;
187 unsigned fi_stride;
182 unsigned fi_stride;
188 unsigned c_ix, f_ix, n_counts;
183 unsigned c_ix, f_ix, n_counts;
189
184
190 #if 0
191 memset (&this_object, 0, sizeof (this_object));
192 memset (&object, 0, sizeof (object));
193
194
195 /* Totals for this object file. */
196 ci_ptr = gi_ptr->counts;
197 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
198 {
199 if (!((1 << t_ix) & gi_ptr->ctr_mask))
200 continue;
201
202 cs_ptr = &this_object.ctrs[t_ix];
203 cs_ptr->num += ci_ptr->num;
204 for (c_num = 0; c_num < ci_ptr->num; c_num++)
205 {
206 cs_ptr->sum_all += ci_ptr->values[c_num];
207 if (cs_ptr->run_max < ci_ptr->values[c_num])
208 cs_ptr->run_max = ci_ptr->values[c_num];
209 }
210
211 ci_ptr++;
212 }
213 #endif
214
215 c_ix = 0;
185 c_ix = 0;
216 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
186 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
217 if ((1 << t_ix) & gi_ptr->ctr_mask)
187 if ((1 << t_ix) & gi_ptr->ctr_mask)
218 {
188 {
219 values[c_ix] = gi_ptr->counts[c_ix].values;
189 values[c_ix] = gi_ptr->counts[c_ix].values;
220 c_ix++;
190 c_ix++;
221 }
191 }
222
192
223 /* Calculate the function_info stride. This depends on the
193 /* Calculate the function_info stride. This depends on the
224 number of counter types being measured. */
194 number of counter types being measured. */
225 fi_stride = sizeof (struct gcov_fn_info) + c_ix * sizeof (unsigned);
195 fi_stride = sizeof (struct gcov_fn_info) + c_ix * sizeof (unsigned);
226 if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned))
196 if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned))
227 {
197 {
228 fi_stride += __alignof__ (struct gcov_fn_info) - 1;
198 fi_stride += __alignof__ (struct gcov_fn_info) - 1;
229 fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1);
199 fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1);
230 }
200 }
231
201
232 if (!gcov_open (gi_ptr->filename))
202 if (!gcov_open (gi_ptr->filename))
233 {
203 {
234 printf ("profiling:%s:Cannot open\n", gi_ptr->filename);
204 printf ("profiling:%s:Cannot open\n", gi_ptr->filename);
235 continue;
205 continue;
236 }
206 }
237
207
238 #if 0
239 tag = gcov_read_unsigned ();
240 if (tag)
241 {
242 /* Merge data from file. */
243 if (tag != GCOV_DATA_MAGIC)
244 {
245 fprintf (stderr, "profiling:%s:Not a gcov data file\n",
246 gi_ptr->filename);
247 read_fatal:;
248 gcov_close ();
249 continue;
250 }
251 length = gcov_read_unsigned ();
252 if (!gcov_version (gi_ptr, length))
253 goto read_fatal;
254
255 length = gcov_read_unsigned ();
256 if (length != gi_ptr->stamp)
257 {
258 /* Read from a different compilation. Overwrite the
259 file. */
260 gcov_truncate ();
261 goto rewrite;
262 }
263
264 /* Merge execution counts for each function. */
265 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
266 {
267 fi_ptr = (const struct gcov_fn_info *)
268 ((const char *) gi_ptr->functions + f_ix * fi_stride);
269 tag = gcov_read_unsigned ();
270 length = gcov_read_unsigned ();
271
272 /* Check function. */
273 if (tag != GCOV_TAG_FUNCTION
274 || length != GCOV_TAG_FUNCTION_LENGTH
275 || gcov_read_unsigned () != fi_ptr->ident
276 || gcov_read_unsigned () != fi_ptr->checksum)
277 {
278 read_mismatch:;
279 fprintf (stderr, "profiling:%s:Merge mismatch for %s\n",
280 gi_ptr->filename,
281 f_ix + 1 ? "function" : "summaries");
282 goto read_fatal;
283 }
284
285 c_ix = 0;
286 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
287 {
288 gcov_merge_fn merge;
289
290 if (!((1 << t_ix) & gi_ptr->ctr_mask))
291 continue;
292
293 n_counts = fi_ptr->n_ctrs[c_ix];
294 merge = gi_ptr->counts[c_ix].merge;
295
296 tag = gcov_read_unsigned ();
297 length = gcov_read_unsigned ();
298 if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
299 || length != GCOV_TAG_COUNTER_LENGTH (n_counts))
300 goto read_mismatch;
301 (*merge) (values[c_ix], n_counts);
302 values[c_ix] += n_counts;
303 c_ix++;
304 }
305 if ((error = gcov_is_error ()))
306 goto read_error;
307 }
308
309 f_ix = ~0u;
310 /* Check program & object summary */
311 while (1)
312 {
313 gcov_position_t base = gcov_position ();
314 int is_program;
315
316 tag = gcov_read_unsigned ();
317 if (!tag)
318 break;
319 length = gcov_read_unsigned ();
320 is_program = tag == GCOV_TAG_PROGRAM_SUMMARY;
321 if (length != GCOV_TAG_SUMMARY_LENGTH
322 || (!is_program && tag != GCOV_TAG_OBJECT_SUMMARY))
323 goto read_mismatch;
324 gcov_read_summary (is_program ? &program : &object);
325 if ((error = gcov_is_error ()))
326 goto read_error;
327 if (is_program && program.checksum == gcov_crc32)
328 {
329 summary_pos = base;
330 goto rewrite;
331 }
332 }
333 }
334
335 if (!gcov_is_eof ())
336 {
337 read_error:;
338 fprintf (stderr, error < 0 ? "profiling:%s:Overflow merging\n"
339 : "profiling:%s:Error merging\n", gi_ptr->filename);
340 goto read_fatal;
341 }
342 rewrite:;
343 gcov_rewrite ();
344 if (!summary_pos)
345 memset (&program, 0, sizeof (program));
346 /* Merge the summaries. */
347 f_ix = ~0u;
348 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
349 {
350 cs_obj = &object.ctrs[t_ix];
351 cs_tobj = &this_object.ctrs[t_ix];
352 cs_prg = &program.ctrs[t_ix];
353 cs_tprg = &this_program.ctrs[t_ix];
354 cs_all = &all.ctrs[t_ix];
355
356 if ((1 << t_ix) & gi_ptr->ctr_mask)
357 {
358 if (!cs_obj->runs++)
359 cs_obj->num = cs_tobj->num;
360 else if (cs_obj->num != cs_tobj->num)
361 goto read_mismatch;
362 cs_obj->sum_all += cs_tobj->sum_all;
363 if (cs_obj->run_max < cs_tobj->run_max)
364 cs_obj->run_max = cs_tobj->run_max;
365 cs_obj->sum_max += cs_tobj->run_max;
366
367 if (!cs_prg->runs++)
368 cs_prg->num = cs_tprg->num;
369 else if (cs_prg->num != cs_tprg->num)
370 goto read_mismatch;
371 cs_prg->sum_all += cs_tprg->sum_all;
372 if (cs_prg->run_max < cs_tprg->run_max)
373 cs_prg->run_max = cs_tprg->run_max;
374 cs_prg->sum_max += cs_tprg->run_max;
375 }
376 else if (cs_obj->num || cs_prg->num)
377 goto read_mismatch;
378
379 if (!cs_all->runs && cs_prg->runs)
380 memcpy (cs_all, cs_prg, sizeof (*cs_all));
381 else if (!all.checksum
382 && (!GCOV_LOCKED || cs_all->runs == cs_prg->runs)
383 && memcmp (cs_all, cs_prg, sizeof (*cs_all)))
384 {
385 fprintf (stderr, "profiling:%s:Invocation mismatch - some data files may have been removed%s",
386 gi_ptr->filename, GCOV_LOCKED
387 ? "" : " or concurrent update without locking support");
388 all.checksum = ~0u;
389 }
390 }
391
392 c_ix = 0;
393 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
394 if ((1 << t_ix) & gi_ptr->ctr_mask)
395 {
396 values[c_ix] = gi_ptr->counts[c_ix].values;
397 c_ix++;
398 }
399
400 #endif
401 program.checksum = gcov_crc32;
208 program.checksum = gcov_crc32;
402
209
403 /* Write out the data. */
210 /* Write out the data. */
404 gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
211 gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
405 gcov_write_unsigned (gi_ptr->stamp);
212 gcov_write_unsigned (gi_ptr->stamp);
406
213
407 /* Write execution counts for each function. */
214 /* Write execution counts for each function. */
408 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
215 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
409 {
216 {
410 fi_ptr = (const struct gcov_fn_info *)
217 fi_ptr = (const struct gcov_fn_info *)
411 ((const char *) gi_ptr->functions + f_ix * fi_stride);
218 ((const char *) gi_ptr->functions + f_ix * fi_stride);
412
219
413 /* Announce function. */
220 /* Announce function. */
414 gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
221 gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
415 gcov_write_unsigned (fi_ptr->ident);
222 gcov_write_unsigned (fi_ptr->ident);
416 gcov_write_unsigned (fi_ptr->checksum);
223 gcov_write_unsigned (fi_ptr->checksum);
417
224
418 c_ix = 0;
225 c_ix = 0;
419 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
226 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
420 {
227 {
421 gcov_type *c_ptr;
228 gcov_type *c_ptr;
422
229
423 if (!((1 << t_ix) & gi_ptr->ctr_mask))
230 if (!((1 << t_ix) & gi_ptr->ctr_mask))
424 continue;
231 continue;
425
232
426 n_counts = fi_ptr->n_ctrs[c_ix];
233 n_counts = fi_ptr->n_ctrs[c_ix];
427
234
428 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
235 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
429 GCOV_TAG_COUNTER_LENGTH (n_counts));
236 GCOV_TAG_COUNTER_LENGTH (n_counts));
430 c_ptr = values[c_ix];
237 c_ptr = values[c_ix];
431 while (n_counts--)
238 while (n_counts--)
432 gcov_write_counter (*c_ptr++);
239 gcov_write_counter (*c_ptr++);
433
240
434 values[c_ix] = c_ptr;
241 values[c_ix] = c_ptr;
435 c_ix++;
242 c_ix++;
436 }
243 }
437 }
244 }
438
245
439 /* Object file summary. */
440 // gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
441
442 /* Generate whole program statistics. */
443 // gcov_seek (summary_pos);
444 // gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program);
445 gcov_send();
246 gcov_send();
446 gcov_close();
247 gcov_close();
447 /* if ((error = gcov_send ()))
248
448 fprintf (stderr, error < 0 ?
449 "profiling:%s:Overflow writing\n" :
450 "profiling:%s:Error writing\n",
451 gi_ptr->filename);*/
452 }
249 }
453
250
454 printf("_GCOVEXIT_END_,core%d\n", coreId);
251 printf("_GCOVEXIT_END_,core%d\n", coreId);
455 }
252 }
456
253
457
254
458 /* Called before fork or exec - write out profile information gathered so
255 /* Called before fork or exec - write out profile information gathered so
459 far and reset it to zero. This avoids duplication or loss of the
256 far and reset it to zero. This avoids duplication or loss of the
460 profile information gathered so far. */
257 profile information gathered so far. */
461
258
462 void
259 void
463 __gcov_flush (void)
260 __gcov_flush (void)
464 {
261 {
465 const struct gcov_info *gi_ptr;
262 const struct gcov_info *gi_ptr;
466
263
467 gcov_exit ();
264 gcov_exit ();
468 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
265 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
469 {
266 {
470 unsigned t_ix;
267 unsigned t_ix;
471 const struct gcov_ctr_info *ci_ptr;
268 const struct gcov_ctr_info *ci_ptr;
472
269
473 for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++)
270 for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++)
474 if ((1 << t_ix) & gi_ptr->ctr_mask)
271 if ((1 << t_ix) & gi_ptr->ctr_mask)
475 {
272 {
476 memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
273 memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
477 ci_ptr++;
274 ci_ptr++;
478 }
275 }
479 }
276 }
480 }
277 }
481
278
482
279
483
280
484 /* Open a gcov file. NAME is the name of the file to open and MODE
281 /* Open a gcov file. NAME is the name of the file to open and MODE
485 indicates whether a new file should be created, or an existing file
282 indicates whether a new file should be created, or an existing file
486 opened for modification. If MODE is >= 0 an existing file will be
283 opened for modification. If MODE is >= 0 an existing file will be
487 opened, if possible, and if MODE is <= 0, a new file will be
284 opened, if possible, and if MODE is <= 0, a new file will be
488 created. Use MODE=0 to attempt to reopen an existing file and then
285 created. Use MODE=0 to attempt to reopen an existing file and then
489 fall back on creating a new one. Return zero on failure, >0 on
286 fall back on creating a new one. Return zero on failure, >0 on
490 opening an existing file and <0 on creating a new one. */
287 opening an existing file and <0 on creating a new one. */
491 GCOV_LINKAGE int gcov_open(const char *name)
288 GCOV_LINKAGE int gcov_open(const char *name)
492 {
289 {
493 // gcov_var.start is cleared in the gcov_close function.
290 // gcov_var.start is cleared in the gcov_close function.
494 // If this variable is not cleared...ERROR
291 // If this variable is not cleared...ERROR
495 if( gcov_var.start != 0 )
292 if( gcov_var.start != 0 )
496 return 0;
293 return 0;
497
294
498 // Clear everything
295 // Clear everything
499 gcov_var.start = 0;
296 gcov_var.start = 0;
500 gcov_var.offset = gcov_var.length = 0;
297 gcov_var.offset = gcov_var.length = 0;
501 gcov_var.overread = -1u;
298 gcov_var.overread = -1u;
502 gcov_var.error = 0;
299 gcov_var.error = 0;
503
300
504
301
505 // copy the filename in the gcov_var structure
302 // copy the filename in the gcov_var structure
506 strcpy(gcov_var.filename, name);
303 strcpy(gcov_var.filename, name);
507
304
508
305
509 // return 1 means everything is OK
306 // return 1 means everything is OK
510 return 1;
307 return 1;
511 }
308 }
512
309
513 /* Close the current gcov file. Flushes data to disk. Returns nonzero
310 /* Close the current gcov file. Flushes data to disk. Returns nonzero
514 on failure or error flag set. */
311 on failure or error flag set. */
515
312
516 GCOV_LINKAGE int gcov_send (void)
313 GCOV_LINKAGE int gcov_send (void)
517 {
314 {
518 /*printf("%s: file %s\n", __func__, gcov_var.filename);*/
315 /*printf("%s: file %s\n", __func__, gcov_var.filename);*/
519 if (gcov_var.offset)
316 if (gcov_var.offset)
520 gcov_write_block (gcov_var.offset);
317 gcov_write_block (gcov_var.offset);
521
318
522 gcov_var.length = 0;
319 gcov_var.length = 0;
523 return gcov_var.error;
320 return gcov_var.error;
524 }
321 }
525
322
526 GCOV_LINKAGE int gcov_close(void)
323 GCOV_LINKAGE int gcov_close(void)
527 {
324 {
528 /*printf("%s: %s\n", __func__, gcov_var.filename);*/
529 memset(gcov_var.filename, 0, strlen(gcov_var.filename));
325 memset(gcov_var.filename, 0, strlen(gcov_var.filename));
530
326
531 // Clear the start variable because will be tested in the gcov_open
327 // Clear the start variable because will be tested in the gcov_open
532 // function
328 // function
533 gcov_var.start = 0;
329 gcov_var.start = 0;
534
330
535 // Return the error, not sure whether the error is modifed.
331 // Return the error, not sure whether the error is modifed.
536 return gcov_var.error;
332 return gcov_var.error;
537 }
333 }
538
334
539 /* Write out the
540 current block, if needs be. */
541 /*static void gcov_write_block (unsigned size) {
542 unsigned int bw = 0;
543 unsigned int i;
544
545 printf("_GCOV_,%s,", gcov_var.filename);
546 for(i = 0; i < size << 2; i++) {
547 char str[5] = {0};
548
549 printf("%02X", ((unsigned char*)(gcov_var.buffer))[i]);
550 }
551 printf("\n");
552
553 gcov_var.start += size;
554 gcov_var.offset -= size;
555 }*/
556
335
557 static void gcov_write_block (unsigned size) {
336 static void gcov_write_block (unsigned size) {
558 unsigned char *buffer = (unsigned char*) gcov_var.buffer;
337 unsigned char *buffer = (unsigned char*) gcov_var.buffer;
559 unsigned int i;
338 unsigned int i;
560
339
561 printf("_GCOV_,%s,", gcov_var.filename);
340 printf("_GCOV_,%s,", gcov_var.filename);
562 /* to speed up the printing process, we display bytes 4 by 4 */
341 /* to speed up the printing process, we display bytes 4 by 4 */
563 for(i = 0; i < size; i++) {
342 for(i = 0; i < size; i++) {
564 printf("%02X%02X%02X%02X", (unsigned int)(buffer[0]),
343 printf("%02X%02X%02X%02X", (unsigned int)(buffer[0]),
565 (unsigned int)(buffer[1]),
344 (unsigned int)(buffer[1]),
566 (unsigned int)(buffer[2]),
345 (unsigned int)(buffer[2]),
567 (unsigned int)(buffer[3]));
346 (unsigned int)(buffer[3]));
568
347
569 buffer += sizeof(gcov_unsigned_t);
348 buffer += sizeof(gcov_unsigned_t);
570 }
349 }
571 printf("\n");
350 printf("\n");
572
351
573 gcov_var.start += size;
352 gcov_var.start += size;
574 gcov_var.offset -= size;
353 gcov_var.offset -= size;
575 }
354 }
576
355
577 /* Allocate space to write BYTES bytes to the gcov file. Return a
356 /* Allocate space to write BYTES bytes to the gcov file. Return a
578 pointer to those bytes, or NULL on failure. */
357 pointer to those bytes, or NULL on failure. */
579
358
580 static gcov_unsigned_t *gcov_write_words (unsigned words) {
359 static gcov_unsigned_t *gcov_write_words (unsigned words) {
581 gcov_unsigned_t *result;
360 gcov_unsigned_t *result;
582
361
583 GCOV_CHECK_WRITING ();
362 GCOV_CHECK_WRITING ();
584 if (gcov_var.offset >= GCOV_BLOCK_SIZE)
363 if (gcov_var.offset >= GCOV_BLOCK_SIZE)
585 {
364 {
586 gcov_write_block (GCOV_BLOCK_SIZE);
365 gcov_write_block (GCOV_BLOCK_SIZE);
587 if (gcov_var.offset)
366 if (gcov_var.offset)
588 {
367 {
589 GCOV_CHECK (gcov_var.offset == 1);
368 GCOV_CHECK (gcov_var.offset == 1);
590 memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4);
369 memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4);
591 }
370 }
592 }
371 }
593 result = &gcov_var.buffer[gcov_var.offset];
372 result = &gcov_var.buffer[gcov_var.offset];
594 gcov_var.offset += words;
373 gcov_var.offset += words;
595
374
596 return result;
375 return result;
597 }
376 }
598
377
599 /* Write unsigned VALUE to coverage file. Sets error flag
378 /* Write unsigned VALUE to coverage file. Sets error flag
600 appropriately. */
379 appropriately. */
601
380
602 GCOV_LINKAGE void
381 GCOV_LINKAGE void
603 gcov_write_unsigned (gcov_unsigned_t value)
382 gcov_write_unsigned (gcov_unsigned_t value)
604 {
383 {
605 gcov_unsigned_t *buffer = gcov_write_words (1);
384 gcov_unsigned_t *buffer = gcov_write_words (1);
606
385
607 buffer[0] = value;
386 buffer[0] = value;
608 }
387 }
609
388
610 /* Write counter VALUE to coverage file. Sets error flag
389 /* Write counter VALUE to coverage file. Sets error flag
611 appropriately. */
390 appropriately. */
612
391
613 GCOV_LINKAGE void
392 GCOV_LINKAGE void
614 gcov_write_counter (gcov_type value)
393 gcov_write_counter (gcov_type value)
615 {
394 {
616 gcov_unsigned_t *buffer = gcov_write_words (2);
395 gcov_unsigned_t *buffer = gcov_write_words (2);
617
396
618 buffer[0] = (gcov_unsigned_t) value;
397 buffer[0] = (gcov_unsigned_t) value;
619 if (sizeof (value) > sizeof (gcov_unsigned_t))
398 if (sizeof (value) > sizeof (gcov_unsigned_t))
620 buffer[1] = (gcov_unsigned_t) (value >> 32);
399 buffer[1] = (gcov_unsigned_t) (value >> 32);
621 else
400 else
622 buffer[1] = 0;
401 buffer[1] = 0;
623
402
624 // if (value < 0)
625 // gcov_var.error = -1;
626 }
403 }
627
404
628 /* Write a tag TAG and length LENGTH. */
405 /* Write a tag TAG and length LENGTH. */
629
406
630 GCOV_LINKAGE void
407 GCOV_LINKAGE void
631 gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length)
408 gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length)
632 {
409 {
633 gcov_unsigned_t *buffer = gcov_write_words (2);
410