##// END OF EJS Templates
Added gcov support...
jeandet -
r387:96eb9489ec21 No PWD scrub with... draft
parent child
Show More
@@ -0,0 +1,17
1 cmake_minimum_required(VERSION 3.6)
2 project(libgcov C)
3 include(sparc-rtems)
4 include(cppcheck)
5
6 set(LIB_GCOV_SOURCES
7 gcov-io.c
8 gcov-io.h
9 gcov-iov.h
10 libgcov.c
11 )
12
13 add_library(gcov STATIC ${LIB_GCOV_SOURCES})
14
15 add_custom_target(gcovr
16 COMMAND gcovr --exclude='.*gcov.*' --gcov-executable=${rtems_dir}/bin/sparc-rtems-gcov --object-directory ${CMAKE_BINARY_DIR} -r ${CMAKE_SOURCE_DIR} --html --html-details -o ${CMAKE_CURRENT_BINARY_DIR}/gcov.html && xdg-open ${CMAKE_CURRENT_BINARY_DIR}/gcov.html
17 )
@@ -0,0 +1,38
1 #!/usr/bin/env python3
2
3 __author__ = "Alexis Jeandet"
4 __copyright__ = "Copyright 2018, Laboratory of Plasma Physics"
5 __credits__ = []
6 __license__ = "GPLv2"
7 __version__ = "1.0.0"
8 __maintainer__ = "Alexis Jeandet"
9 __email__ = "alexis.jeandet@member.fsf.org"
10 __status__ = "Development"
11
12 import time
13 import sys
14 import os
15 import serial
16 import argparse
17 from datetime import datetime
18
19 parser = argparse.ArgumentParser()
20 parser.add_argument("-f", "--gcov-file", help="Gcov output file generated by record_lfr_console.py")
21 args = parser.parse_args()
22
23
24
25 def main():
26 with open(args.gcov_file,'r') as gcov:
27 for line in gcov.readlines():
28 head,dest_file,data = line.split(',')
29 if head == '_GCOV_':
30 print(f"Writing {dest_file}\n")
31 with open(dest_file,'wb') as gcda_file:
32 gcda_file.write(bytes([int(''.join(value),16) for value in zip(data[::2],data[1::2]) ]))
33 else:
34 raise
35
36
37 if __name__ == "__main__":
38 main()
This diff has been collapsed as it changes many lines, (820 lines changed) Show them Hide them
@@ -0,0 +1,820
1 /* Test for GCC >= 3.4.4 && <= 4.4.6 */
2 //#if ( ( __GNUC__ > 3 ) || \
3 // ( __GNUC__ == 3 && __GNUC_MINOR__ > 4 )|| \
4 // ( __GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ >= 4 ) ) && \
5 // ( ( __GNUC__ < 4 ) || \
6 // ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 )|| \
7 // ( __GNUC__ == 4 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ <= 6 ) )
8 /*
9 * =====================================================================================
10 *
11 * Filename: gcov-io.c
12 *
13 * Description: This is the I/O file for embedded systems
14 *
15 * Version: 1.0
16 * Created: 03/04/08 09:51:59
17 * Revision: none
18 * Compiler: gcc
19 *
20 * Author: Aitor Viana Sanchez (avs), aitor.viana.sanchez@esa.int
21 * Company: European Space Agency (ESA-ESTEC)
22 *
23 * =====================================================================================
24 */
25
26 /* File format for coverage information
27 Copyright (C) 1996, 1997, 1998, 2000, 2002,
28 2003 Free Software Foundation, Inc.
29 Contributed by Bob Manson <manson@cygnus.com>.
30 Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
31
32 This file is part of GCC.
33
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
36 Software Foundation; either version 2, or (at your option) any later
37 version.
38
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
41 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
42 for more details.
43
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
46 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
47 02111-1307, USA. */
48
49 #include <stdio.h>
50 #include <stdlib.h> /* for atexit() */
51 #include <string.h>
52 #include "gcov-io.h"
53
54 /* Routines declared in gcov-io.h. This file should be #included by
55 another source file, after having #included gcov-io.h. */
56
57
58 /* This function shall be defined somewhere else */
59 //int send_data(unsigned char * buffer, unsigned int size);
60
61 /*-----------------------------------------------------------------------------
62 * PRIVATE INTERFACE
63 *-----------------------------------------------------------------------------*/
64
65 static void gcov_write_block (unsigned);
66 static gcov_unsigned_t *gcov_write_words (unsigned);
67 GCOV_LINKAGE int gcov_send (void);
68 GCOV_LINKAGE int gcov_close(void);
69 //static const gcov_unsigned_t *gcov_read_words (unsigned);
70
71 extern struct gcov_info * gcov_list;
72 extern gcov_unsigned_t gcov_crc32;
73
74 int dev_id = 0;
75
76 /*
77 * === FUNCTION ======================================================================
78 * Name: from_file
79 * Description: This function just return the given parameter
80 * =====================================================================================
81 */
82 static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
83 {
84 return value;
85 }
86
87 /*
88 * === FUNCTION ======================================================================
89 * Name: gcov_version
90 * Description: This function returns TRUE (1) if the gcov version is the
91 * version expected. The function returns FALSE (0) in any other case.
92 * =====================================================================================
93 */
94 static int gcov_version (struct gcov_info *ptr, gcov_unsigned_t version)
95 {
96 if (version != GCOV_VERSION)
97 {
98 char v[4], e[4];
99
100 GCOV_UNSIGNED2STRING (v, version);
101 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
102
103 printf ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
104 ptr->filename, e, v);
105
106 return 0;
107 }
108 return 1;
109 }
110
111
112 /*-----------------------------------------------------------------------------
113 * PUBLIC INTERFACE
114 *-----------------------------------------------------------------------------*/
115
116 /* Dump the coverage counts. We merge with existing counts when
117 possible, to avoid growing the .da files ad infinitum. We use this
118 program's checksum to make sure we only accumulate whole program
119 statistics to the correct summary. An object file might be embedded
120 in two separate programs, and we must keep the two program
121 summaries separate. */
122
123 /*
124 * === FUNCTION ======================================================================
125 * Name: gcov_exit
126 * Description: This function dumps the coverage couns. The merging with
127 * existing counts is not done in embedded systems.
128 * =====================================================================================
129 */
130 void gcov_exit (void)
131 {
132 struct gcov_info *gi_ptr;
133 struct gcov_summary this_program;
134 struct gcov_summary all;
135 struct gcov_ctr_summary *cs_ptr;
136 const struct gcov_ctr_info *ci_ptr;
137 unsigned t_ix;
138 gcov_unsigned_t c_num;
139 unsigned long coreId = 0;
140
141 /* retrieve the id of the CPU the program is running on */
142 #ifdef LEON3
143 __asm__ __volatile__("rd %%asr17,%0\n\t"
144 "srl %0,28,%0" :
145 "=&r" (coreId) : );
146 #endif
147
148 printf("_GCOVEXIT_BEGIN_,core%d\n", coreId); /* see also _GCOVEXIT_END_ */
149
150 if(gcov_list == (void*)0x0)
151 printf("%s: gcov_list == NULL\n", __func__);
152
153 memset (&all, 0, sizeof (all));
154 /* Find the totals for this execution. */
155 memset (&this_program, 0, sizeof (this_program));
156 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
157 {
158
159 ci_ptr = gi_ptr->counts;
160 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
161 {
162 if (!((1 << t_ix) & gi_ptr->ctr_mask))
163 continue;
164
165 cs_ptr = &this_program.ctrs[t_ix];
166 cs_ptr->num += ci_ptr->num;
167 for (c_num = 0; c_num < ci_ptr->num; c_num++)
168 {
169 cs_ptr->sum_all += ci_ptr->values[c_num];
170 if (cs_ptr->run_max < ci_ptr->values[c_num])
171 cs_ptr->run_max = ci_ptr->values[c_num];
172 }
173 ci_ptr++;
174 }
175 }
176 /* Now merge each file. */
177 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
178 {
179 // struct gcov_summary this_object, object;
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;
185 gcov_type *values[GCOV_COUNTERS];
186 const struct gcov_fn_info *fi_ptr;
187 unsigned fi_stride;
188 unsigned c_ix, f_ix, n_counts;
189
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;
216 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
217 if ((1 << t_ix) & gi_ptr->ctr_mask)
218 {
219 values[c_ix] = gi_ptr->counts[c_ix].values;
220 c_ix++;
221 }
222
223 /* Calculate the function_info stride. This depends on the
224 number of counter types being measured. */
225 fi_stride = sizeof (struct gcov_fn_info) + c_ix * sizeof (unsigned);
226 if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned))
227 {
228 fi_stride += __alignof__ (struct gcov_fn_info) - 1;
229 fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1);
230 }
231
232 if (!gcov_open (gi_ptr->filename))
233 {
234 printf ("profiling:%s:Cannot open\n", gi_ptr->filename);
235 continue;
236 }
237
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;
402
403 /* Write out the data. */
404 gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
405 gcov_write_unsigned (gi_ptr->stamp);
406
407 /* Write execution counts for each function. */
408 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
409 {
410 fi_ptr = (const struct gcov_fn_info *)
411 ((const char *) gi_ptr->functions + f_ix * fi_stride);
412
413 /* Announce function. */
414 gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
415 gcov_write_unsigned (fi_ptr->ident);
416 gcov_write_unsigned (fi_ptr->checksum);
417
418 c_ix = 0;
419 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
420 {
421 gcov_type *c_ptr;
422
423 if (!((1 << t_ix) & gi_ptr->ctr_mask))
424 continue;
425
426 n_counts = fi_ptr->n_ctrs[c_ix];
427
428 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
429 GCOV_TAG_COUNTER_LENGTH (n_counts));
430 c_ptr = values[c_ix];
431 while (n_counts--)
432 gcov_write_counter (*c_ptr++);
433
434 values[c_ix] = c_ptr;
435 c_ix++;
436 }
437 }
438
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();
446 gcov_close();
447 /* if ((error = gcov_send ()))
448 fprintf (stderr, error < 0 ?
449 "profiling:%s:Overflow writing\n" :
450 "profiling:%s:Error writing\n",
451 gi_ptr->filename);*/
452 }
453
454 printf("_GCOVEXIT_END_,core%d\n", coreId);
455 }
456
457
458 /* 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
460 profile information gathered so far. */
461
462 void
463 __gcov_flush (void)
464 {
465 const struct gcov_info *gi_ptr;
466
467 gcov_exit ();
468 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
469 {
470 unsigned t_ix;
471 const struct gcov_ctr_info *ci_ptr;
472
473 for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++)
474 if ((1 << t_ix) & gi_ptr->ctr_mask)
475 {
476 memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
477 ci_ptr++;
478 }
479 }
480 }
481
482
483
484 /* 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
486 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
488 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
490 opening an existing file and <0 on creating a new one. */
491 GCOV_LINKAGE int gcov_open(const char *name)
492 {
493 // gcov_var.start is cleared in the gcov_close function.
494 // If this variable is not cleared...ERROR
495 if( gcov_var.start != 0 )
496 return 0;
497
498 // Clear everything
499 gcov_var.start = 0;
500 gcov_var.offset = gcov_var.length = 0;
501 gcov_var.overread = -1u;
502 gcov_var.error = 0;
503
504
505 // copy the filename in the gcov_var structure
506 strcpy(gcov_var.filename, name);
507
508
509 // return 1 means everything is OK
510 return 1;
511 }
512
513 /* Close the current gcov file. Flushes data to disk. Returns nonzero
514 on failure or error flag set. */
515
516 GCOV_LINKAGE int gcov_send (void)
517 {
518 /*printf("%s: file %s\n", __func__, gcov_var.filename);*/
519 if (gcov_var.offset)
520 gcov_write_block (gcov_var.offset);
521
522 gcov_var.length = 0;
523 return gcov_var.error;
524 }
525
526 GCOV_LINKAGE int gcov_close(void)
527 {
528 /*printf("%s: %s\n", __func__, gcov_var.filename);*/
529 memset(gcov_var.filename, 0, strlen(gcov_var.filename));
530
531 // Clear the start variable because will be tested in the gcov_open
532 // function
533 gcov_var.start = 0;
534
535 // Return the error, not sure whether the error is modifed.
536 return gcov_var.error;
537 }
538
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
557 static void gcov_write_block (unsigned size) {
558 unsigned char *buffer = (unsigned char*) gcov_var.buffer;
559 unsigned int i;
560
561 printf("_GCOV_,%s,", gcov_var.filename);
562 /* to speed up the printing process, we display bytes 4 by 4 */
563 for(i = 0; i < size; i++) {
564 printf("%02X%02X%02X%02X", (unsigned int)(buffer[0]),
565 (unsigned int)(buffer[1]),
566 (unsigned int)(buffer[2]),
567 (unsigned int)(buffer[3]));
568
569 buffer += sizeof(gcov_unsigned_t);
570 }
571 printf("\n");
572
573 gcov_var.start += size;
574 gcov_var.offset -= size;
575 }
576
577 /* Allocate space to write BYTES bytes to the gcov file. Return a
578 pointer to those bytes, or NULL on failure. */
579
580 static gcov_unsigned_t *gcov_write_words (unsigned words) {
581 gcov_unsigned_t *result;
582
583 GCOV_CHECK_WRITING ();
584 if (gcov_var.offset >= GCOV_BLOCK_SIZE)
585 {
586 gcov_write_block (GCOV_BLOCK_SIZE);
587 if (gcov_var.offset)
588 {
589 GCOV_CHECK (gcov_var.offset == 1);
590 memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4);
591 }
592 }
593 result = &gcov_var.buffer[gcov_var.offset];
594 gcov_var.offset += words;
595
596 return result;
597 }
598
599 /* Write unsigned VALUE to coverage file. Sets error flag
600 appropriately. */
601
602 GCOV_LINKAGE void
603 gcov_write_unsigned (gcov_unsigned_t value)
604 {
605 gcov_unsigned_t *buffer = gcov_write_words (1);
606
607 buffer[0] = value;
608 }
609
610 /* Write counter VALUE to coverage file. Sets error flag
611 appropriately. */
612
613 GCOV_LINKAGE void
614 gcov_write_counter (gcov_type value)
615 {
616 gcov_unsigned_t *buffer = gcov_write_words (2);
617
618 buffer[0] = (gcov_unsigned_t) value;
619 if (sizeof (value) > sizeof (gcov_unsigned_t))
620 buffer[1] = (gcov_unsigned_t) (value >> 32);
621 else
622 buffer[1] = 0;
623
624 // if (value < 0)
625 // gcov_var.error = -1;
626 }
627
628 /* Write a tag TAG and length LENGTH. */
629
630 GCOV_LINKAGE void
631 gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length)
632 {
633 gcov_unsigned_t *buffer = gcov_write_words (2);
634
635 buffer[0] = tag;
636 buffer[1] = length;
637 }
638
639 /* Write a summary structure to the gcov file. Return nonzero on
640 overflow. */
641
642 GCOV_LINKAGE void
643 gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary)
644 {
645 unsigned ix;
646 const struct gcov_ctr_summary *csum;
647
648 gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH);
649 gcov_write_unsigned (summary->checksum);
650 for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
651 {
652 gcov_write_unsigned (csum->num);
653 gcov_write_unsigned (csum->runs);
654 gcov_write_counter (csum->sum_all);
655 gcov_write_counter (csum->run_max);
656 gcov_write_counter (csum->sum_max);
657 }
658 }
659
660 /* Return a pointer to read BYTES bytes from the gcov file. Returns
661 NULL on failure (read past EOF). */
662 #if 0
663 GCOV_LINKAGE const gcov_unsigned_t *
664 gcov_read_words (unsigned words)
665 {
666 const gcov_unsigned_t *result;
667 unsigned excess = gcov_var.length - gcov_var.offset;
668
669 GCOV_CHECK_READING ();
670 if (excess < words)
671 {
672 gcov_var.start += gcov_var.offset;
673 if (excess)
674 {
675 GCOV_CHECK (excess == 1);
676 memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4);
677 }
678 gcov_var.offset = 0;
679 gcov_var.length = excess;
680 GCOV_CHECK (!gcov_var.length || gcov_var.length == 1);
681 excess = GCOV_BLOCK_SIZE;
682 excess = fread (gcov_var.buffer + gcov_var.length,
683 1, excess << 2, gcov_var.file) >> 2;
684 gcov_var.length += excess;
685 if (gcov_var.length < words)
686 {
687 gcov_var.overread += words - gcov_var.length;
688 gcov_var.length = 0;
689 return 0;
690 }
691 }
692 result = &gcov_var.buffer[gcov_var.offset];
693 gcov_var.offset += words;
694 return result;
695 }
696
697
698 /* Read unsigned value from a coverage file. Sets error flag on file
699 error, overflow flag on overflow */
700
701 GCOV_LINKAGE gcov_unsigned_t
702 gcov_read_unsigned (void)
703 {
704 gcov_unsigned_t value;
705 const gcov_unsigned_t *buffer = gcov_read_words (1);
706
707 if (!buffer)
708 return 0;
709 value = from_file (buffer[0]);
710 return value;
711 }
712
713 /* Read counter value from a coverage file. Sets error flag on file
714 error, overflow flag on overflow */
715 #endif
716 GCOV_LINKAGE gcov_type
717 gcov_read_counter (void)
718 {
719 #if 0
720 gcov_type value;
721 const gcov_unsigned_t *buffer = gcov_read_words (2);
722
723 if (!buffer)
724 return 0;
725 value = from_file (buffer[0]);
726 if (sizeof (value) > sizeof (gcov_unsigned_t))
727 value |= ((gcov_type) from_file (buffer[1])) << 32;
728 else if (buffer[1])
729 gcov_var.error = -1;
730
731 if (value < 0)
732 gcov_var.error = -1;
733 return value;
734 #endif
735 return 0;
736 }
737 #if 0
738
739 /* Read string from coverage file. Returns a pointer to a static
740 buffer, or NULL on empty string. You must copy the string before
741 calling another gcov function. */
742
743 GCOV_LINKAGE void
744 gcov_read_summary (struct gcov_summary *summary)
745 {
746 unsigned ix;
747 struct gcov_ctr_summary *csum;
748
749 summary->checksum = gcov_read_unsigned ();
750 for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
751 {
752 csum->num = gcov_read_unsigned ();
753 csum->runs = gcov_read_unsigned ();
754 csum->sum_all = gcov_read_counter ();
755 csum->run_max = gcov_read_counter ();
756 csum->sum_max = gcov_read_counter ();
757 }
758 }
759
760 /* Move to the a set position in a gcov file. BASE is zero to move to
761 the end, and nonzero to move to that position. */
762
763 GCOV_LINKAGE void
764 gcov_seek (gcov_position_t base)
765 {
766 GCOV_CHECK_WRITING ();
767 if (gcov_var.offset)
768 gcov_write_block (gcov_var.offset);
769 fseek (gcov_var.file, base << 2, base ? SEEK_SET : SEEK_END);
770 gcov_var.start = ftell (gcov_var.file) >> 2;
771 }
772
773 #endif
774
775 /* Add a new object file onto the bb chain. Invoked automatically
776 when running an object file's global ctors. */
777
778 void
779 __gcov_init (struct gcov_info *info)
780 {
781 if (!info->version)
782 return;
783 if (gcov_version (info, info->version))
784 {
785 const char *ptr = info->filename;
786 gcov_unsigned_t crc32 = gcov_crc32;
787
788 /* Added by LESIA*/
789 /*printf("Covered file: %s\n", info->filename);*/
790 /* End of Added by LESIA*/
791
792 do
793 {
794 unsigned ix;
795 gcov_unsigned_t value = *ptr << 24;
796
797 for (ix = 8; ix--; value <<= 1)
798 {
799 gcov_unsigned_t feedback;
800
801 feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
802 crc32 <<= 1;
803 crc32 ^= feedback;
804 }
805 }
806 while (*ptr++);
807
808 gcov_crc32 = crc32;
809
810 if (!gcov_list)
811 atexit (gcov_exit);
812
813 info->next = gcov_list;
814 gcov_list = info;
815 }
816 else
817 printf("%s: Version mismatch\n", "WARNING");
818 info->version = 0;
819 }
820 //#endif /* __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ */
This diff has been collapsed as it changes many lines, (531 lines changed) Show them Hide them
@@ -0,0 +1,531
1 /* Test for GCC >= 3.4.4 && <= 4.4.6 */
2 //#if ( ( __GNUC__ > 3 ) || \
3 // ( __GNUC__ == 3 && __GNUC_MINOR__ > 4 )|| \
4 // ( __GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ >= 4 ) ) && \
5 // ( ( __GNUC__ < 4 ) || \
6 // ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 )|| \
7 // ( __GNUC__ == 4 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ <= 6 ) )
8 //#include <stdlib.h>
9 //#include <stdio.h>
10 /* File format for coverage information
11 Copyright (C) 1996, 1997, 1998, 2000, 2002,
12 2003, 2004 Free Software Foundation, Inc.
13 Contributed by Bob Manson <manson@cygnus.com>.
14 Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
15
16 This file is part of GCC.
17
18 GCC is free software; you can redistribute it and/or modify it under
19 the terms of the GNU General Public License as published by the Free
20 Software Foundation; either version 2, or (at your option) any later
21 version.
22
23 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
24 WARRANTY; without even the implied warranty of MERCHANTABILITY or
25 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 for more details.
27
28 You should have received a copy of the GNU General Public License
29 along with GCC; see the file COPYING. If not, write to the Free
30 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
31 02111-1307, USA. */
32
33 /* As a special exception, if you link this library with other files,
34 some of which are compiled with GCC, to produce an executable,
35 this library does not by itself cause the resulting executable
36 to be covered by the GNU General Public License.
37 This exception does not however invalidate any other reasons why
38 the executable file might be covered by the GNU General Public License. */
39
40 /* Coverage information is held in two files. A notes file, which is
41 generated by the compiler, and a data file, which is generated
42 by the program under test. Both files use a similar structure. We
43 do not attempt to make these files backwards compatible with
44 previous versions, as you only need coverage information when
45 developing a program. We do hold version information, so that
46 mismatches can be detected, and we use a format that allows tools
47 to skip information they do not understand or are not interested
48 in.
49
50 Numbers are recorded in the 32 bit unsigned binary form of the
51 endianness of the machine generating the file. 64 bit numbers are
52 stored as two 32 bit numbers, the low part first. Strings are
53 padded with 1 to 4 NUL bytes, to bring the length up to a multiple
54 of 4. The number of 4 bytes is stored, followed by the padded
55 string. Zero length and NULL strings are simply stored as
56 a length of zero (they have no trailing NUL or padding).
57
58 int32: byte3 byte2 byte1 byte0 | byte0 byte1 byte2 byte3
59 int64: int32:low int32:high
60 string: int32:0 | int32:length char* char:0 padding
61 padding: | char:0 | char:0 char:0 | char:0 char:0 char:0
62 item: int32 | int64 | string
63
64 The basic format of the files is
65
66 file : int32:magic int32:version int32:stamp record*
67
68 The magic ident is different for the notes and the data files. The
69 magic ident is used to determine the endianness of the file, when
70 reading. The version is the same for both files and is derived
71 from gcc's version number. The stamp value is used to synchronize
72 note and data files and to synchronize merging within a data
73 file. It need not be an absolute time stamp, merely a ticker that
74 increments fast enough and cycles slow enough to distinguish
75 different compile/run/compile cycles.
76
77 Although the ident and version are formally 32 bit numbers, they
78 are derived from 4 character ASCII strings. The version number
79 consists of the single character major version number, a two
80 character minor version number (leading zero for versions less than
81 10), and a single character indicating the status of the release.
82 That will be 'e' experimental, 'p' prerelease and 'r' for release.
83 Because, by good fortune, these are in alphabetical order, string
84 collating can be used to compare version strings. Be aware that
85 the 'e' designation will (naturally) be unstable and might be
86 incompatible with itself. For gcc 3.4 experimental, it would be
87 '304e' (0x33303465). When the major version reaches 10, the
88 letters A-Z will be used. Assuming minor increments releases every
89 6 months, we have to make a major increment every 50 years.
90 Assuming major increments releases every 5 years, we're ok for the
91 next 155 years -- good enough for me.
92
93 A record has a tag, length and variable amount of data.
94
95 record: header data
96 header: int32:tag int32:length
97 data: item*
98
99 Records are not nested, but there is a record hierarchy. Tag
100 numbers reflect this hierarchy. Tags are unique across note and
101 data files. Some record types have a varying amount of data. The
102 LENGTH is the number of 4bytes that follow and is usually used to
103 determine how much data. The tag value is split into 4 8-bit
104 fields, one for each of four possible levels. The most significant
105 is allocated first. Unused levels are zero. Active levels are
106 odd-valued, so that the LSB of the level is one. A sub-level
107 incorporates the values of its superlevels. This formatting allows
108 you to determine the tag hierarchy, without understanding the tags
109 themselves, and is similar to the standard section numbering used
110 in technical documents. Level values [1..3f] are used for common
111 tags, values [41..9f] for the notes file and [a1..ff] for the data
112 file.
113
114 The basic block graph file contains the following records
115 note: unit function-graph*
116 unit: header int32:checksum string:source
117 function-graph: announce_function basic_blocks {arcs | lines}*
118 announce_function: header int32:ident int32:checksum
119 string:name string:source int32:lineno
120 basic_block: header int32:flags*
121 arcs: header int32:block_no arc*
122 arc: int32:dest_block int32:flags
123 lines: header int32:block_no line*
124 int32:0 string:NULL
125 line: int32:line_no | int32:0 string:filename
126
127 The BASIC_BLOCK record holds per-bb flags. The number of blocks
128 can be inferred from its data length. There is one ARCS record per
129 basic block. The number of arcs from a bb is implicit from the
130 data length. It enumerates the destination bb and per-arc flags.
131 There is one LINES record per basic block, it enumerates the source
132 lines which belong to that basic block. Source file names are
133 introduced by a line number of 0, following lines are from the new
134 source file. The initial source file for the function is NULL, but
135 the current source file should be remembered from one LINES record
136 to the next. The end of a block is indicated by an empty filename
137 - this does not reset the current source file. Note there is no
138 ordering of the ARCS and LINES records: they may be in any order,
139 interleaved in any manner. The current filename follows the order
140 the LINES records are stored in the file, *not* the ordering of the
141 blocks they are for.
142
143 The data file contains the following records.
144 data: {unit function-data* summary:object summary:program*}*
145 unit: header int32:checksum
146 function-data: announce_function arc_counts
147 announce_function: header int32:ident int32:checksum
148 arc_counts: header int64:count*
149 summary: int32:checksum {count-summary}GCOV_COUNTERS
150 count-summary: int32:num int32:runs int64:sum
151 int64:max int64:sum_max
152
153 The ANNOUNCE_FUNCTION record is the same as that in the note file,
154 but without the source location. The ARC_COUNTS gives the counter
155 values for those arcs that are instrumented. The SUMMARY records
156 give information about the whole object file and about the whole
157 program. The checksum is used for whole program summaries, and
158 disambiguates different programs which include the same
159 instrumented object file. There may be several program summaries,
160 each with a unique checksum. The object summary's checksum is zero.
161 Note that the data file might contain information from several runs
162 concatenated, or the data might be merged.
163
164 This file is included by both the compiler, gcov tools and the
165 runtime support library libgcov. IN_LIBGCOV and IN_GCOV are used to
166 distinguish which case is which. If IN_LIBGCOV is nonzero,
167 libgcov is being built. If IN_GCOV is nonzero, the gcov tools are
168 being built. Otherwise the compiler is being built. IN_GCOV may be
169 positive or negative. If positive, we are compiling a tool that
170 requires additional functions (see the code for knowledge of what
171 those functions are). */
172
173 #ifndef GCC_GCOV_IO_H
174 #define GCC_GCOV_IO_H
175
176 typedef unsigned int gcov_unsigned_t;
177 typedef unsigned int gcov_position_t;
178
179 typedef unsigned long long gcov_type;
180
181 /* No tengo ni idea de que es el SETLKW, asi que de momento el target
182 * no tiene de eso */
183
184 //#if defined (TARGET_HAS_F_SETLKW)
185 //#define GCOV_LOCKED 1
186 //#else
187 #define GCOV_LOCKED 0
188 //#endif
189 //#endif
190
191
192
193 /* In gcov we want function linkage to be static. In the compiler we want
194 it extern, so that they can be accessed from elsewhere. In libgcov we
195 need these functions to be extern, so prefix them with __gcov. In
196 libgcov they must also be hidden so that the instance in the executable
197 is not also used in a DSO. */
198
199 #define gcov_var __gcov_var
200 #define gcov_open __gcov_open
201 #define gcov_close __gcov_close
202 #define gcov_write_tag_length __gcov_write_tag_length
203 #define gcov_position __gcov_position
204 #define gcov_seek __gcov_seek
205 #define gcov_rewrite __gcov_rewrite
206 #define gcov_is_error __gcov_is_error
207 #define gcov_is_eof __gcov_is_eof
208 #define gcov_write_unsigned __gcov_write_unsigned
209 #define gcov_write_counter __gcov_write_counter
210 #define gcov_write_summary __gcov_write_summary
211 #define gcov_read_unsigned __gcov_read_unsigned
212 #define gcov_read_counter __gcov_read_counter
213 #define gcov_read_summary __gcov_read_summary
214
215 /* Esto no tengo ni repajolera idea de para que vale */
216
217 /* Poison these, so they don't accidentally slip in. */
218 //#pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length
219 //#pragma GCC poison gcov_read_string gcov_sync gcov_time gcov_magic
220
221 #ifdef HAVE_GAS_HIDDEN
222 #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
223 #else
224 #define ATTRIBUTE_HIDDEN
225 #endif
226
227 #ifndef GCOV_LINKAGE
228 #define GCOV_LINKAGE extern
229 //#define GCOV_LINKAGE
230 #endif
231
232 /* File suffixes. */
233 #define GCOV_DATA_SUFFIX ".gcda"
234 #define GCOV_NOTE_SUFFIX ".gcno"
235
236 /* File magic. Must not be palindromes. */
237 #define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */
238 #define GCOV_NOTE_MAGIC ((gcov_unsigned_t)0x67636e6f) /* "gcno" */
239
240 /* gcov-iov.h is automatically generated by the makefile from
241 version.c, it looks like
242 #define GCOV_VERSION ((gcov_unsigned_t)0x89abcdef)
243 */
244 #include "gcov-iov.h"
245
246 /* Convert a magic or version number to a 4 character string. */
247 #define GCOV_UNSIGNED2STRING(ARRAY,VALUE) \
248 ((ARRAY)[0] = (char)((VALUE) >> 24), \
249 (ARRAY)[1] = (char)((VALUE) >> 16), \
250 (ARRAY)[2] = (char)((VALUE) >> 8), \
251 (ARRAY)[3] = (char)((VALUE) >> 0))
252
253 /* The record tags. Values [1..3f] are for tags which may be in either
254 file. Values [41..9f] for those in the note file and [a1..ff] for
255 the data file. */
256
257 #define GCOV_TAG_FUNCTION ((gcov_unsigned_t)0x01000000)
258 #define GCOV_TAG_FUNCTION_LENGTH (2)
259 #define GCOV_TAG_BLOCKS ((gcov_unsigned_t)0x01410000)
260 #define GCOV_TAG_BLOCKS_LENGTH(NUM) (NUM)
261 #define GCOV_TAG_BLOCKS_NUM(LENGTH) (LENGTH)
262 #define GCOV_TAG_ARCS ((gcov_unsigned_t)0x01430000)
263 #define GCOV_TAG_ARCS_LENGTH(NUM) (1 + (NUM) * 2)
264 #define GCOV_TAG_ARCS_NUM(LENGTH) (((LENGTH) - 1) / 2)
265 #define GCOV_TAG_LINES ((gcov_unsigned_t)0x01450000)
266 #define GCOV_TAG_COUNTER_BASE ((gcov_unsigned_t)0x01a10000)