##// END OF EJS Templates
Added gcov support...
Added gcov support Imported sources from LESIA (thanks!) Added CMake option Coverage to enable code coverage on LFR and link with modified libgcov Added target to build html reports

File last commit:

r387:96eb9489ec21 No PWD scrub with...
r387:96eb9489ec21 No PWD scrub with...
Show More
gcov-io.c
820 lines | 25.2 KiB | text/x-c | CLexer
/* Test for GCC >= 3.4.4 && <= 4.4.6 */
//#if ( ( __GNUC__ > 3 ) || \
// ( __GNUC__ == 3 && __GNUC_MINOR__ > 4 )|| \
// ( __GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ >= 4 ) ) && \
// ( ( __GNUC__ < 4 ) || \
// ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 )|| \
// ( __GNUC__ == 4 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ <= 6 ) )
/*
* =====================================================================================
*
* Filename: gcov-io.c
*
* Description: This is the I/O file for embedded systems
*
* Version: 1.0
* Created: 03/04/08 09:51:59
* Revision: none
* Compiler: gcc
*
* Author: Aitor Viana Sanchez (avs), aitor.viana.sanchez@esa.int
* Company: European Space Agency (ESA-ESTEC)
*
* =====================================================================================
*/
/* File format for coverage information
Copyright (C) 1996, 1997, 1998, 2000, 2002,
2003 Free Software Foundation, Inc.
Contributed by Bob Manson <manson@cygnus.com>.
Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include <stdio.h>
#include <stdlib.h> /* for atexit() */
#include <string.h>
#include "gcov-io.h"
/* Routines declared in gcov-io.h. This file should be #included by
another source file, after having #included gcov-io.h. */
/* This function shall be defined somewhere else */
//int send_data(unsigned char * buffer, unsigned int size);
/*-----------------------------------------------------------------------------
* PRIVATE INTERFACE
*-----------------------------------------------------------------------------*/
static void gcov_write_block (unsigned);
static gcov_unsigned_t *gcov_write_words (unsigned);
GCOV_LINKAGE int gcov_send (void);
GCOV_LINKAGE int gcov_close(void);
//static const gcov_unsigned_t *gcov_read_words (unsigned);
extern struct gcov_info * gcov_list;
extern gcov_unsigned_t gcov_crc32;
int dev_id = 0;
/*
* === FUNCTION ======================================================================
* Name: from_file
* Description: This function just return the given parameter
* =====================================================================================
*/
static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
{
return value;
}
/*
* === FUNCTION ======================================================================
* Name: gcov_version
* Description: This function returns TRUE (1) if the gcov version is the
* version expected. The function returns FALSE (0) in any other case.
* =====================================================================================
*/
static int gcov_version (struct gcov_info *ptr, gcov_unsigned_t version)
{
if (version != GCOV_VERSION)
{
char v[4], e[4];
GCOV_UNSIGNED2STRING (v, version);
GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
printf ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
ptr->filename, e, v);
return 0;
}
return 1;
}
/*-----------------------------------------------------------------------------
* PUBLIC INTERFACE
*-----------------------------------------------------------------------------*/
/* Dump the coverage counts. We merge with existing counts when
possible, to avoid growing the .da files ad infinitum. We use this
program's checksum to make sure we only accumulate whole program
statistics to the correct summary. An object file might be embedded
in two separate programs, and we must keep the two program
summaries separate. */
/*
* === FUNCTION ======================================================================
* Name: gcov_exit
* Description: This function dumps the coverage couns. The merging with
* existing counts is not done in embedded systems.
* =====================================================================================
*/
void gcov_exit (void)
{
struct gcov_info *gi_ptr;
struct gcov_summary this_program;
struct gcov_summary all;
struct gcov_ctr_summary *cs_ptr;
const struct gcov_ctr_info *ci_ptr;
unsigned t_ix;
gcov_unsigned_t c_num;
unsigned long coreId = 0;
/* retrieve the id of the CPU the program is running on */
#ifdef LEON3
__asm__ __volatile__("rd %%asr17,%0\n\t"
"srl %0,28,%0" :
"=&r" (coreId) : );
#endif
printf("_GCOVEXIT_BEGIN_,core%d\n", coreId); /* see also _GCOVEXIT_END_ */
if(gcov_list == (void*)0x0)
printf("%s: gcov_list == NULL\n", __func__);
memset (&all, 0, sizeof (all));
/* Find the totals for this execution. */
memset (&this_program, 0, sizeof (this_program));
for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
{
ci_ptr = gi_ptr->counts;
for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
{
if (!((1 << t_ix) & gi_ptr->ctr_mask))
continue;
cs_ptr = &this_program.ctrs[t_ix];
cs_ptr->num += ci_ptr->num;
for (c_num = 0; c_num < ci_ptr->num; c_num++)
{
cs_ptr->sum_all += ci_ptr->values[c_num];
if (cs_ptr->run_max < ci_ptr->values[c_num])
cs_ptr->run_max = ci_ptr->values[c_num];
}
ci_ptr++;
}
}
/* Now merge each file. */
for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
{
// struct gcov_summary this_object, object;
// struct gcov_ctr_summary *cs_obj, *cs_tobj, *cs_prg, *cs_tprg, *cs_all;
// int error = 0;
// gcov_unsigned_t tag, length;
// gcov_position_t summary_pos = 0;
struct gcov_summary program;
gcov_type *values[GCOV_COUNTERS];
const struct gcov_fn_info *fi_ptr;
unsigned fi_stride;
unsigned c_ix, f_ix, n_counts;
#if 0
memset (&this_object, 0, sizeof (this_object));
memset (&object, 0, sizeof (object));
/* Totals for this object file. */
ci_ptr = gi_ptr->counts;
for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
{
if (!((1 << t_ix) & gi_ptr->ctr_mask))
continue;
cs_ptr = &this_object.ctrs[t_ix];
cs_ptr->num += ci_ptr->num;
for (c_num = 0; c_num < ci_ptr->num; c_num++)
{
cs_ptr->sum_all += ci_ptr->values[c_num];
if (cs_ptr->run_max < ci_ptr->values[c_num])
cs_ptr->run_max = ci_ptr->values[c_num];
}
ci_ptr++;
}
#endif
c_ix = 0;
for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
if ((1 << t_ix) & gi_ptr->ctr_mask)
{
values[c_ix] = gi_ptr->counts[c_ix].values;
c_ix++;
}
/* Calculate the function_info stride. This depends on the
number of counter types being measured. */
fi_stride = sizeof (struct gcov_fn_info) + c_ix * sizeof (unsigned);
if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned))
{
fi_stride += __alignof__ (struct gcov_fn_info) - 1;
fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1);
}
if (!gcov_open (gi_ptr->filename))
{
printf ("profiling:%s:Cannot open\n", gi_ptr->filename);
continue;
}
#if 0
tag = gcov_read_unsigned ();
if (tag)
{
/* Merge data from file. */
if (tag != GCOV_DATA_MAGIC)
{
fprintf (stderr, "profiling:%s:Not a gcov data file\n",
gi_ptr->filename);
read_fatal:;
gcov_close ();
continue;
}
length = gcov_read_unsigned ();
if (!gcov_version (gi_ptr, length))
goto read_fatal;
length = gcov_read_unsigned ();
if (length != gi_ptr->stamp)
{
/* Read from a different compilation. Overwrite the
file. */
gcov_truncate ();
goto rewrite;
}
/* Merge execution counts for each function. */
for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
{
fi_ptr = (const struct gcov_fn_info *)
((const char *) gi_ptr->functions + f_ix * fi_stride);
tag = gcov_read_unsigned ();
length = gcov_read_unsigned ();
/* Check function. */
if (tag != GCOV_TAG_FUNCTION
|| length != GCOV_TAG_FUNCTION_LENGTH
|| gcov_read_unsigned () != fi_ptr->ident
|| gcov_read_unsigned () != fi_ptr->checksum)
{
read_mismatch:;
fprintf (stderr, "profiling:%s:Merge mismatch for %s\n",
gi_ptr->filename,
f_ix + 1 ? "function" : "summaries");
goto read_fatal;
}
c_ix = 0;
for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
{
gcov_merge_fn merge;
if (!((1 << t_ix) & gi_ptr->ctr_mask))
continue;
n_counts = fi_ptr->n_ctrs[c_ix];
merge = gi_ptr->counts[c_ix].merge;
tag = gcov_read_unsigned ();
length = gcov_read_unsigned ();
if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
|| length != GCOV_TAG_COUNTER_LENGTH (n_counts))
goto read_mismatch;
(*merge) (values[c_ix], n_counts);
values[c_ix] += n_counts;
c_ix++;
}
if ((error = gcov_is_error ()))
goto read_error;
}
f_ix = ~0u;
/* Check program & object summary */
while (1)
{
gcov_position_t base = gcov_position ();
int is_program;
tag = gcov_read_unsigned ();
if (!tag)
break;
length = gcov_read_unsigned ();
is_program = tag == GCOV_TAG_PROGRAM_SUMMARY;
if (length != GCOV_TAG_SUMMARY_LENGTH
|| (!is_program && tag != GCOV_TAG_OBJECT_SUMMARY))
goto read_mismatch;
gcov_read_summary (is_program ? &program : &object);
if ((error = gcov_is_error ()))
goto read_error;
if (is_program && program.checksum == gcov_crc32)
{
summary_pos = base;
goto rewrite;
}
}
}
if (!gcov_is_eof ())
{
read_error:;
fprintf (stderr, error < 0 ? "profiling:%s:Overflow merging\n"
: "profiling:%s:Error merging\n", gi_ptr->filename);
goto read_fatal;
}
rewrite:;
gcov_rewrite ();
if (!summary_pos)
memset (&program, 0, sizeof (program));
/* Merge the summaries. */
f_ix = ~0u;
for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
{
cs_obj = &object.ctrs[t_ix];
cs_tobj = &this_object.ctrs[t_ix];
cs_prg = &program.ctrs[t_ix];
cs_tprg = &this_program.ctrs[t_ix];
cs_all = &all.ctrs[t_ix];
if ((1 << t_ix) & gi_ptr->ctr_mask)
{
if (!cs_obj->runs++)
cs_obj->num = cs_tobj->num;
else if (cs_obj->num != cs_tobj->num)
goto read_mismatch;
cs_obj->sum_all += cs_tobj->sum_all;
if (cs_obj->run_max < cs_tobj->run_max)
cs_obj->run_max = cs_tobj->run_max;
cs_obj->sum_max += cs_tobj->run_max;
if (!cs_prg->runs++)
cs_prg->num = cs_tprg->num;
else if (cs_prg->num != cs_tprg->num)
goto read_mismatch;
cs_prg->sum_all += cs_tprg->sum_all;
if (cs_prg->run_max < cs_tprg->run_max)
cs_prg->run_max = cs_tprg->run_max;
cs_prg->sum_max += cs_tprg->run_max;
}
else if (cs_obj->num || cs_prg->num)
goto read_mismatch;
if (!cs_all->runs && cs_prg->runs)
memcpy (cs_all, cs_prg, sizeof (*cs_all));
else if (!all.checksum
&& (!GCOV_LOCKED || cs_all->runs == cs_prg->runs)
&& memcmp (cs_all, cs_prg, sizeof (*cs_all)))
{
fprintf (stderr, "profiling:%s:Invocation mismatch - some data files may have been removed%s",
gi_ptr->filename, GCOV_LOCKED
? "" : " or concurrent update without locking support");
all.checksum = ~0u;
}
}
c_ix = 0;
for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
if ((1 << t_ix) & gi_ptr->ctr_mask)
{
values[c_ix] = gi_ptr->counts[c_ix].values;
c_ix++;
}
#endif
program.checksum = gcov_crc32;
/* Write out the data. */
gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
gcov_write_unsigned (gi_ptr->stamp);
/* Write execution counts for each function. */
for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
{
fi_ptr = (const struct gcov_fn_info *)
((const char *) gi_ptr->functions + f_ix * fi_stride);
/* Announce function. */
gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
gcov_write_unsigned (fi_ptr->ident);
gcov_write_unsigned (fi_ptr->checksum);
c_ix = 0;
for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
{
gcov_type *c_ptr;
if (!((1 << t_ix) & gi_ptr->ctr_mask))
continue;
n_counts = fi_ptr->n_ctrs[c_ix];
gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
GCOV_TAG_COUNTER_LENGTH (n_counts));
c_ptr = values[c_ix];
while (n_counts--)
gcov_write_counter (*c_ptr++);
values[c_ix] = c_ptr;
c_ix++;
}
}
/* Object file summary. */
// gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
/* Generate whole program statistics. */
// gcov_seek (summary_pos);
// gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program);
gcov_send();
gcov_close();
/* if ((error = gcov_send ()))
fprintf (stderr, error < 0 ?
"profiling:%s:Overflow writing\n" :
"profiling:%s:Error writing\n",
gi_ptr->filename);*/
}
printf("_GCOVEXIT_END_,core%d\n", coreId);
}
/* Called before fork or exec - write out profile information gathered so
far and reset it to zero. This avoids duplication or loss of the
profile information gathered so far. */
void
__gcov_flush (void)
{
const struct gcov_info *gi_ptr;
gcov_exit ();
for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
{
unsigned t_ix;
const struct gcov_ctr_info *ci_ptr;
for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++)
if ((1 << t_ix) & gi_ptr->ctr_mask)
{
memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
ci_ptr++;
}
}
}
/* Open a gcov file. NAME is the name of the file to open and MODE
indicates whether a new file should be created, or an existing file
opened for modification. If MODE is >= 0 an existing file will be
opened, if possible, and if MODE is <= 0, a new file will be
created. Use MODE=0 to attempt to reopen an existing file and then
fall back on creating a new one. Return zero on failure, >0 on
opening an existing file and <0 on creating a new one. */
GCOV_LINKAGE int gcov_open(const char *name)
{
// gcov_var.start is cleared in the gcov_close function.
// If this variable is not cleared...ERROR
if( gcov_var.start != 0 )
return 0;
// Clear everything
gcov_var.start = 0;
gcov_var.offset = gcov_var.length = 0;
gcov_var.overread = -1u;
gcov_var.error = 0;
// copy the filename in the gcov_var structure
strcpy(gcov_var.filename, name);
// return 1 means everything is OK
return 1;
}
/* Close the current gcov file. Flushes data to disk. Returns nonzero
on failure or error flag set. */
GCOV_LINKAGE int gcov_send (void)
{
/*printf("%s: file %s\n", __func__, gcov_var.filename);*/
if (gcov_var.offset)
gcov_write_block (gcov_var.offset);
gcov_var.length = 0;
return gcov_var.error;
}
GCOV_LINKAGE int gcov_close(void)
{
/*printf("%s: %s\n", __func__, gcov_var.filename);*/
memset(gcov_var.filename, 0, strlen(gcov_var.filename));
// Clear the start variable because will be tested in the gcov_open
// function
gcov_var.start = 0;
// Return the error, not sure whether the error is modifed.
return gcov_var.error;
}
/* Write out the
current block, if needs be. */
/*static void gcov_write_block (unsigned size) {
unsigned int bw = 0;
unsigned int i;
printf("_GCOV_,%s,", gcov_var.filename);
for(i = 0; i < size << 2; i++) {
char str[5] = {0};
printf("%02X", ((unsigned char*)(gcov_var.buffer))[i]);
}
printf("\n");
gcov_var.start += size;
gcov_var.offset -= size;
}*/
static void gcov_write_block (unsigned size) {
unsigned char *buffer = (unsigned char*) gcov_var.buffer;
unsigned int i;
printf("_GCOV_,%s,", gcov_var.filename);
/* to speed up the printing process, we display bytes 4 by 4 */
for(i = 0; i < size; i++) {
printf("%02X%02X%02X%02X", (unsigned int)(buffer[0]),
(unsigned int)(buffer[1]),
(unsigned int)(buffer[2]),
(unsigned int)(buffer[3]));
buffer += sizeof(gcov_unsigned_t);
}
printf("\n");
gcov_var.start += size;
gcov_var.offset -= size;
}
/* Allocate space to write BYTES bytes to the gcov file. Return a
pointer to those bytes, or NULL on failure. */
static gcov_unsigned_t *gcov_write_words (unsigned words) {
gcov_unsigned_t *result;
GCOV_CHECK_WRITING ();
if (gcov_var.offset >= GCOV_BLOCK_SIZE)
{
gcov_write_block (GCOV_BLOCK_SIZE);
if (gcov_var.offset)
{
GCOV_CHECK (gcov_var.offset == 1);
memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4);
}
}
result = &gcov_var.buffer[gcov_var.offset];
gcov_var.offset += words;
return result;
}
/* Write unsigned VALUE to coverage file. Sets error flag
appropriately. */
GCOV_LINKAGE void
gcov_write_unsigned (gcov_unsigned_t value)
{
gcov_unsigned_t *buffer = gcov_write_words (1);
buffer[0] = value;
}
/* Write counter VALUE to coverage file. Sets error flag
appropriately. */
GCOV_LINKAGE void
gcov_write_counter (gcov_type value)
{
gcov_unsigned_t *buffer = gcov_write_words (2);
buffer[0] = (gcov_unsigned_t) value;
if (sizeof (value) > sizeof (gcov_unsigned_t))
buffer[1] = (gcov_unsigned_t) (value >> 32);
else
buffer[1] = 0;
// if (value < 0)
// gcov_var.error = -1;
}
/* Write a tag TAG and length LENGTH. */
GCOV_LINKAGE void
gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length)
{
gcov_unsigned_t *buffer = gcov_write_words (2);
buffer[0] = tag;
buffer[1] = length;
}
/* Write a summary structure to the gcov file. Return nonzero on
overflow. */
GCOV_LINKAGE void
gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary)
{
unsigned ix;
const struct gcov_ctr_summary *csum;
gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH);
gcov_write_unsigned (summary->checksum);
for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
{
gcov_write_unsigned (csum->num);
gcov_write_unsigned (csum->runs);
gcov_write_counter (csum->sum_all);
gcov_write_counter (csum->run_max);
gcov_write_counter (csum->sum_max);
}
}
/* Return a pointer to read BYTES bytes from the gcov file. Returns
NULL on failure (read past EOF). */
#if 0
GCOV_LINKAGE const gcov_unsigned_t *
gcov_read_words (unsigned words)
{
const gcov_unsigned_t *result;
unsigned excess = gcov_var.length - gcov_var.offset;
GCOV_CHECK_READING ();
if (excess < words)
{
gcov_var.start += gcov_var.offset;
if (excess)
{
GCOV_CHECK (excess == 1);
memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4);
}
gcov_var.offset = 0;
gcov_var.length = excess;
GCOV_CHECK (!gcov_var.length || gcov_var.length == 1);
excess = GCOV_BLOCK_SIZE;
excess = fread (gcov_var.buffer + gcov_var.length,
1, excess << 2, gcov_var.file) >> 2;
gcov_var.length += excess;
if (gcov_var.length < words)
{
gcov_var.overread += words - gcov_var.length;
gcov_var.length = 0;
return 0;
}
}
result = &gcov_var.buffer[gcov_var.offset];
gcov_var.offset += words;
return result;
}
/* Read unsigned value from a coverage file. Sets error flag on file
error, overflow flag on overflow */
GCOV_LINKAGE gcov_unsigned_t
gcov_read_unsigned (void)
{
gcov_unsigned_t value;
const gcov_unsigned_t *buffer = gcov_read_words (1);
if (!buffer)
return 0;
value = from_file (buffer[0]);
return value;
}
/* Read counter value from a coverage file. Sets error flag on file
error, overflow flag on overflow */
#endif
GCOV_LINKAGE gcov_type
gcov_read_counter (void)
{
#if 0
gcov_type value;
const gcov_unsigned_t *buffer = gcov_read_words (2);
if (!buffer)
return 0;
value = from_file (buffer[0]);
if (sizeof (value) > sizeof (gcov_unsigned_t))
value |= ((gcov_type) from_file (buffer[1])) << 32;
else if (buffer[1])
gcov_var.error = -1;
if (value < 0)
gcov_var.error = -1;
return value;
#endif
return 0;
}
#if 0
/* Read string from coverage file. Returns a pointer to a static
buffer, or NULL on empty string. You must copy the string before
calling another gcov function. */
GCOV_LINKAGE void
gcov_read_summary (struct gcov_summary *summary)
{
unsigned ix;
struct gcov_ctr_summary *csum;
summary->checksum = gcov_read_unsigned ();
for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
{
csum->num = gcov_read_unsigned ();
csum->runs = gcov_read_unsigned ();
csum->sum_all = gcov_read_counter ();
csum->run_max = gcov_read_counter ();
csum->sum_max = gcov_read_counter ();
}
}
/* Move to the a set position in a gcov file. BASE is zero to move to
the end, and nonzero to move to that position. */
GCOV_LINKAGE void
gcov_seek (gcov_position_t base)
{
GCOV_CHECK_WRITING ();
if (gcov_var.offset)
gcov_write_block (gcov_var.offset);
fseek (gcov_var.file, base << 2, base ? SEEK_SET : SEEK_END);
gcov_var.start = ftell (gcov_var.file) >> 2;
}
#endif
/* Add a new object file onto the bb chain. Invoked automatically
when running an object file's global ctors. */
void
__gcov_init (struct gcov_info *info)
{
if (!info->version)
return;
if (gcov_version (info, info->version))
{
const char *ptr = info->filename;
gcov_unsigned_t crc32 = gcov_crc32;
/* Added by LESIA*/
/*printf("Covered file: %s\n", info->filename);*/
/* End of Added by LESIA*/
do
{
unsigned ix;
gcov_unsigned_t value = *ptr << 24;
for (ix = 8; ix--; value <<= 1)
{
gcov_unsigned_t feedback;
feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
crc32 <<= 1;
crc32 ^= feedback;
}
}
while (*ptr++);
gcov_crc32 = crc32;
if (!gcov_list)
atexit (gcov_exit);
info->next = gcov_list;
gcov_list = info;
}
else
printf("%s: Version mismatch\n", "WARNING");
info->version = 0;
}
//#endif /* __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ */