aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.3/gcc/gcov.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.3/gcc/gcov.c')
-rw-r--r--gcc-4.4.3/gcc/gcov.c501
1 files changed, 500 insertions, 1 deletions
diff --git a/gcc-4.4.3/gcc/gcov.c b/gcc-4.4.3/gcc/gcov.c
index d67e621bc..38937917e 100644
--- a/gcc-4.4.3/gcc/gcov.c
+++ b/gcc-4.4.3/gcc/gcov.c
@@ -209,6 +209,15 @@ typedef struct coverage_info
char *name;
} coverage_t;
+/* Describes PMU profile data for either one source file or for the
+ entire program. */
+
+typedef struct pmu_data
+{
+ ll_infos_t ll_infos;
+ brm_infos_t brm_infos;
+} pmu_data_t;
+
/* Describes a single line of source. Contains a chain of basic blocks
with code on it. */
@@ -242,6 +251,8 @@ typedef struct source_info
coverage_t coverage;
+ pmu_data_t *pmu_data; /* PMU profile information for this file. */
+
/* Functions in this source file. These are in ascending line
number order. */
function_t *functions;
@@ -301,6 +312,10 @@ static int flag_branches = 0;
/* Show unconditional branches too. */
static int flag_unconditional = 0;
+/* Output performance monitoring unit (PMU) data, if available. */
+
+static int flag_pmu_profile = 0;
+
/* Output a gcov file if this is true. This is on by default, and can
be turned off by the -n option. */
@@ -340,6 +355,18 @@ static int flag_preserve_paths = 0;
static int flag_counts = 0;
+/* PMU profile default filename. */
+
+static char pmu_profile_default_filename[] = "pmuprofile.gcda";
+
+/* PMU profile filename where the PMU profile data is read from. */
+
+static char *pmu_profile_filename = 0;
+
+/* PMU data for the entire program. */
+
+static pmu_data_t pmu_global_info;
+
/* Forward declarations. */
static void fnotice (FILE *, const char *, ...) ATTRIBUTE_PRINTF_2;
static int process_args (int, char **);
@@ -361,6 +388,17 @@ static int output_branch_count (FILE *, int, const arc_t *);
static void output_lines (FILE *, const source_t *);
static char *make_gcov_file_name (const char *, const char *);
static void release_structures (void);
+static void process_pmu_profile (void);
+static void filter_pmu_data_lines (source_t *src);
+static void output_pmu_data_header (FILE *gcov_file, pmu_data_t *pmu_data);
+static void output_pmu_data (FILE *gcov_file, const source_t *src,
+ const unsigned line_num);
+static void output_load_latency_line (FILE *fp,
+ const gcov_pmu_ll_info_t *ll_info,
+ gcov_pmu_tool_header_t *tool_header);
+static void output_branch_mispredict_line (FILE *fp,
+ const gcov_pmu_brm_info_t *brm_info);
+
extern int main (int, char **);
int
@@ -383,6 +421,15 @@ main (int argc, char **argv)
if (argc - argno > 1)
multiple_files = 1;
+ /* We read pmu profile first because we later filter
+ src:line_numbers for each source. */
+ if (flag_pmu_profile)
+ {
+ if (!pmu_profile_filename)
+ pmu_profile_filename = pmu_profile_default_filename;
+ process_pmu_profile ();
+ }
+
for (; argno != argc; argno++)
process_file (argv[argno]);
@@ -420,6 +467,7 @@ print_usage (int error_p)
fnotice (file, " -b, --branch-probabilities Include branch probabilities in output\n");
fnotice (file, " -c, --branch-counts Given counts of branches taken\n\
rather than percentages\n");
+ fnotice (file, " -m, --pmu-profile Output PMU profile data if available\n");
fnotice (file, " -n, --no-output Do not create an output file\n");
fnotice (file, " -l, --long-file-names Use long output file names for included\n\
source files\n");
@@ -432,6 +480,7 @@ print_usage (int error_p)
applications. It will output a single\n\
.gcov file per .gcda file. No source file\n\
is required.\n");
+ fnotice (file, " -q, --pmu_profile-path Path for PMU profile (default pmuprofile.gcda)\n");
fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
bug_report_url);
exit (status);
@@ -459,6 +508,7 @@ static const struct option options[] =
{ "all-blocks", no_argument, NULL, 'a' },
{ "branch-probabilities", no_argument, NULL, 'b' },
{ "branch-counts", no_argument, NULL, 'c' },
+ { "pmu-profile", no_argument, NULL, 'm' },
{ "no-output", no_argument, NULL, 'n' },
{ "long-file-names", no_argument, NULL, 'l' },
{ "function-summaries", no_argument, NULL, 'f' },
@@ -467,6 +517,7 @@ static const struct option options[] =
{ "object-file", required_argument, NULL, 'o' },
{ "unconditional-branches", no_argument, NULL, 'u' },
{ "intermediate-format", no_argument, NULL, 'i' },
+ { "pmu_profile-path", required_argument, NULL, 'q' },
{ 0, 0, 0, 0 }
};
@@ -477,7 +528,8 @@ process_args (int argc, char **argv)
{
int opt;
- while ((opt = getopt_long (argc, argv, "abcfhilno:puv", options, NULL)) != -1)
+ while ((opt = getopt_long (argc, argv, "abcfhilmno:q:puv", options, NULL))
+ != -1)
{
switch (opt)
{
@@ -499,6 +551,9 @@ process_args (int argc, char **argv)
case 'l':
flag_long_names = 1;
break;
+ case 'm':
+ flag_pmu_profile = 1;
+ break;
case 'n':
flag_gcov_file = 0;
break;
@@ -508,6 +563,9 @@ process_args (int argc, char **argv)
case 'p':
flag_preserve_paths = 1;
break;
+ case 'q':
+ pmu_profile_filename = optarg;
+ break;
case 'u':
flag_unconditional = 1;
break;
@@ -747,6 +805,8 @@ release_structures (void)
{
function_t *fn;
source_t *src;
+ ll_infos_t *ll_infos = &pmu_global_info.ll_infos;
+ brm_infos_t *brm_infos = &pmu_global_info.brm_infos;
while ((src = sources))
{
@@ -754,6 +814,14 @@ release_structures (void)
free (src->name);
free (src->lines);
+ if (src->pmu_data)
+ {
+ if (src->pmu_data->ll_infos.ll_array)
+ free (src->pmu_data->ll_infos.ll_array);
+ if (src->pmu_data->brm_infos.brm_array)
+ free (src->pmu_data->brm_infos.brm_array);
+ free (src->pmu_data);
+ }
}
while ((fn = functions))
@@ -775,6 +843,42 @@ release_structures (void)
free (fn->blocks);
free (fn->counts);
}
+
+ /* Cleanup PMU load latency info. */
+ if (ll_infos->ll_count)
+ {
+ unsigned i;
+
+ /* delete each element */
+ for (i = 0; i < ll_infos->ll_count; ++i)
+ {
+ if (ll_infos->ll_array[i]->filename)
+ XDELETE (ll_infos->ll_array[i]->filename);
+ XDELETE (ll_infos->ll_array[i]);
+ }
+ /* delete the array itself */
+ XDELETE (ll_infos->ll_array);
+ ll_infos->ll_array = NULL;
+ ll_infos->ll_count = 0;
+ }
+
+ /* Cleanup PMU branch mispredict info. */
+ if (brm_infos->brm_count)
+ {
+ unsigned i;
+
+ /* delete each element */
+ for (i = 0; i < brm_infos->brm_count; ++i)
+ {
+ if (brm_infos->brm_array[i]->filename)
+ XDELETE (brm_infos->brm_array[i]->filename);
+ XDELETE (brm_infos->brm_array[i]);
+ }
+ /* delete the array itself */
+ XDELETE (brm_infos->brm_array);
+ brm_infos->brm_array = NULL;
+ brm_infos->brm_count = 0;
+ }
}
/* Generate the names of the graph and data files. If OBJECT_DIRECTORY
@@ -871,6 +975,7 @@ find_source (const char *file_name)
src->coverage.name = src->name;
src->index = source_index++;
src->next = sources;
+ src->pmu_data = 0;
sources = src;
if (!stat (file_name, &status))
@@ -1792,6 +1897,148 @@ add_line_counts (coverage_t *coverage, function_t *fn)
fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
}
+/* Filter PMU profile global data for lines for SRC. Save PMU info
+ matching the source file and sort them by line number for later
+ line by line processing. */
+
+static void
+filter_pmu_data_lines (source_t *src)
+{
+ unsigned i;
+ int changed;
+ ll_infos_t *ll_infos; /* load latency information for this source */
+ brm_infos_t *brm_infos; /* branch mispredict information for this source */
+
+ if (pmu_global_info.ll_infos.ll_count == 0 &&
+ pmu_global_info.brm_infos.brm_count == 0)
+ /* If there are no global entries, there is nothing to filter. */
+ return;
+
+ src->pmu_data = XCNEW (pmu_data_t);
+ ll_infos = &src->pmu_data->ll_infos;
+ brm_infos = &src->pmu_data->brm_infos;
+ ll_infos->pmu_tool_header = pmu_global_info.ll_infos.pmu_tool_header;
+ brm_infos->pmu_tool_header = pmu_global_info.brm_infos.pmu_tool_header;
+ ll_infos->ll_array = 0;
+ brm_infos->brm_array = 0;
+
+ /* Go over all the load latency entries and save the ones
+ corresponding to this source file. */
+ for (i = 0; i < pmu_global_info.ll_infos.ll_count; ++i)
+ {
+ gcov_pmu_ll_info_t *ll_info = pmu_global_info.ll_infos.ll_array[i];
+ if (0 == strcmp (src->name, ll_info->filename))
+ {
+ if (!ll_infos->ll_array)
+ {
+ ll_infos->ll_count = 0;
+ ll_infos->alloc_ll_count = 64;
+ ll_infos->ll_array = XCNEWVEC (gcov_pmu_ll_info_t *,
+ ll_infos->alloc_ll_count);
+ }
+ /* Found a matching entry, save it. */
+ ll_infos->ll_count++;
+ if (ll_infos->ll_count >= ll_infos->alloc_ll_count)
+ {
+ /* need to realloc */
+ ll_infos->ll_array = (gcov_pmu_ll_info_t **)
+ xrealloc (ll_infos->ll_array, 2 * ll_infos->alloc_ll_count);
+ if (ll_infos->ll_array == NULL) {
+ fprintf (stderr, "Cannot allocate memory for load latency.\n");
+ return;
+ }
+ }
+ ll_infos->ll_array[ll_infos->ll_count - 1] = ll_info;
+ }
+ }
+
+ /* Go over all the branch mispredict entries and save the ones
+ corresponding to this source file. */
+ for (i = 0; i < pmu_global_info.brm_infos.brm_count; ++i)
+ {
+ gcov_pmu_brm_info_t *brm_info = pmu_global_info.brm_infos.brm_array[i];
+ if (0 == strcmp (src->name, brm_info->filename))
+ {
+ if (!brm_infos->brm_array)
+ {
+ brm_infos->brm_count = 0;
+ brm_infos->alloc_brm_count = 64;
+ brm_infos->brm_array = XCNEWVEC (gcov_pmu_brm_info_t *,
+ brm_infos->alloc_brm_count);
+ }
+ /* Found a matching entry, save it. */
+ brm_infos->brm_count++;
+ if (brm_infos->brm_count >= brm_infos->alloc_brm_count)
+ {
+ /* need to realloc */
+ brm_infos->brm_array = (gcov_pmu_brm_info_t **)
+ xrealloc (brm_infos->brm_array, 2 * brm_infos->alloc_brm_count);
+ if (brm_infos->brm_array == NULL) {
+ fprintf (stderr, "Cannot allocate memory for load latency.\n");
+ return;
+ }
+ }
+ brm_infos->brm_array[brm_infos->brm_count - 1] = brm_info;
+ }
+ }
+
+ /* Sort the load latency data according to the line numbers because
+ we later iterate over sources in line number order. Normally we
+ expect the PMU tool to provide sorted data, but a few entries can
+ be out of order. Thus we use a very simple bubble sort here. */
+ if (ll_infos->ll_count > 1)
+ {
+ changed = 1;
+ while (changed)
+ {
+ changed = 0;
+ for (i = 0; i < ll_infos->ll_count - 1; ++i)
+ {
+ gcov_pmu_ll_info_t *item1 = ll_infos->ll_array[i];
+ gcov_pmu_ll_info_t *item2 = ll_infos->ll_array[i+1];
+ if (item1->line > item2->line)
+ {
+ /* swap */
+ gcov_pmu_ll_info_t *tmp = ll_infos->ll_array[i];
+ ll_infos->ll_array[i] = ll_infos->ll_array[i+1];
+ ll_infos->ll_array[i+1] = tmp;
+ changed = 1;
+ }
+ }
+ }
+ }
+
+ /* Similarly, sort branch mispredict info as well. */
+ if (brm_infos->brm_count > 1)
+ {
+ changed = 1;
+ while (changed)
+ {
+ changed = 0;
+ for (i = 0; i < brm_infos->brm_count - 1; ++i)
+ {
+ gcov_pmu_brm_info_t *item1 = brm_infos->brm_array[i];
+ gcov_pmu_brm_info_t *item2 = brm_infos->brm_array[i+1];
+ if (item1->line > item2->line)
+ {
+ /* swap */
+ gcov_pmu_brm_info_t *tmp = brm_infos->brm_array[i];
+ brm_infos->brm_array[i] = brm_infos->brm_array[i+1];
+ brm_infos->brm_array[i+1] = tmp;
+ changed = 1;
+ }
+ }
+ }
+ }
+
+ /* If no matching PMU info was found, relase the structures. */
+ if (!brm_infos->brm_array && !ll_infos->ll_array)
+ {
+ free (src->pmu_data);
+ src->pmu_data = 0;
+ }
+}
+
/* Accumulate the line counts of a file. */
static void
@@ -1801,6 +2048,10 @@ accumulate_line_counts (source_t *src)
function_t *fn, *fn_p, *fn_n;
unsigned ix;
+ if (flag_pmu_profile)
+ /* Filter PMU profile by source files and save into matching line(s). */
+ filter_pmu_data_lines (src);
+
/* Reverse the function order. */
for (fn = src->functions, fn_p = NULL; fn;
fn_p = fn, fn = fn_n)
@@ -2048,6 +2299,9 @@ output_lines (FILE *gcov_file, const source_t *src)
else if (src->file_time == 0)
fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
+ if (src->pmu_data)
+ output_pmu_data_header (gcov_file, src->pmu_data);
+
if (flag_branches)
fn = src->functions;
@@ -2125,6 +2379,10 @@ output_lines (FILE *gcov_file, const source_t *src)
for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
ix += output_branch_count (gcov_file, ix, arc);
}
+
+ /* Output PMU profile info if available. */
+ if (flag_pmu_profile)
+ output_pmu_data (gcov_file, src, line_num);
}
/* Handle all remaining source lines. There may be lines after the
@@ -2148,3 +2406,244 @@ output_lines (FILE *gcov_file, const source_t *src)
if (source_file)
fclose (source_file);
}
+
+/* Print an explanatory header for PMU_DATA into GCOV_FILE. */
+
+static void
+output_pmu_data_header (FILE *gcov_file, pmu_data_t *pmu_data)
+{
+ /* Print header for the applicable PMU events. */
+ fprintf (gcov_file, "%9s:%5d\n", "-", 0);
+ if (pmu_data->ll_infos.ll_count)
+ {
+ char *text = pmu_data->ll_infos.pmu_tool_header->column_description;
+ char c;
+ fprintf (gcov_file, "%9s:%5u: %s", "PMU_LL", 0,
+ pmu_data->ll_infos.pmu_tool_header->column_header);
+ /* The column description is multiline text and we want to print
+ each line separately after formatting it. */
+ fprintf (gcov_file, "%9s:%5u: ", "PMU_LL", 0);
+ while ((c = *text++))
+ {
+ fprintf (gcov_file, "%c", c);
+ /* Do not print a new header on trailing newline. */
+ if (c == '\n' && text[1])
+ fprintf (gcov_file, "%9s:%5u: ", "PMU_LL", 0);
+ }
+ fprintf (gcov_file, "%9s:%5d\n", "-", 0);
+ }
+
+ if (pmu_data->brm_infos.brm_count)
+ {
+
+ fprintf (gcov_file, "%9s:%5d:PMU BRM: line: %s %s %s\n",
+ "-", 0, "count", "self", "address");
+ fprintf (gcov_file, "%9s:%5d: "
+ "count: number of branch mispredicts sampled at this address\n",
+ "-", 0);
+ fprintf (gcov_file, "%9s:%5d: "
+ "self: branch mispredicts as percentage of the entire program\n",
+ "-", 0);
+ fprintf (gcov_file, "%9s:%5d\n", "-", 0);
+ }
+}
+
+/* Output pmu data corresponding to SRC and LINE_NUM into GCOV_FILE. */
+
+static void
+output_pmu_data (FILE *gcov_file, const source_t *src, const unsigned line_num)
+{
+ unsigned i;
+ ll_infos_t *ll_infos;
+ brm_infos_t *brm_infos;
+ gcov_pmu_tool_header_t *tool_header;
+
+ if (!src->pmu_data)
+ return;
+
+ ll_infos = &src->pmu_data->ll_infos;
+ brm_infos = &src->pmu_data->brm_infos;
+
+ if (ll_infos->ll_array)
+ {
+ tool_header = src->pmu_data->ll_infos.pmu_tool_header;
+
+ /* Search PMU load latency data for the matching line
+ numbers. There could be multiple entries with the same line
+ number. We use the fact that line numbers are sorted in
+ ll_array. */
+ for (i = 0; i < ll_infos->ll_count &&
+ ll_infos->ll_array[i]->line <= line_num; ++i)
+ {
+ gcov_pmu_ll_info_t *ll_info = ll_infos->ll_array[i];
+ if (ll_info->line == line_num)
+ output_load_latency_line (gcov_file, ll_info, tool_header);
+ }
+ }
+
+ if (brm_infos->brm_array)
+ {
+ tool_header = src->pmu_data->brm_infos.pmu_tool_header;
+
+ /* Search PMU branch mispredict data for the matching line
+ numbers. There could be multiple entries with the same line
+ number. We use the fact that line numbers are sorted in
+ brm_array. */
+ for (i = 0; i < brm_infos->brm_count &&
+ brm_infos->brm_array[i]->line <= line_num; ++i)
+ {
+ gcov_pmu_brm_info_t *brm_info = brm_infos->brm_array[i];
+ if (brm_info->line == line_num)
+ output_branch_mispredict_line (gcov_file, brm_info);
+ }
+ }
+}
+
+
+/* Output formatted load latency info pointed to by LL_INFO into the
+ open file FP. TOOL_HEADER contains additional explanation of
+ fields. */
+
+static void
+output_load_latency_line (FILE *fp, const gcov_pmu_ll_info_t *ll_info,
+ gcov_pmu_tool_header_t *tool_header ATTRIBUTE_UNUSED)
+{
+ fprintf (fp, "%9s:%5u: ", "PMU_LL", ll_info->line);
+ fprintf (fp, " %u %.2f%% %.2f%% %.2f%% %.2f%% %.2f%% %.2f%% %.2f%% "
+ "%.2f%% %.2f%% " HOST_WIDEST_INT_PRINT_HEX "\n",
+ ll_info->counts,
+ convert_unsigned_to_pct (ll_info->self),
+ convert_unsigned_to_pct (ll_info->cum),
+ convert_unsigned_to_pct (ll_info->lt_10),
+ convert_unsigned_to_pct (ll_info->lt_32),
+ convert_unsigned_to_pct (ll_info->lt_64),
+ convert_unsigned_to_pct (ll_info->lt_256),
+ convert_unsigned_to_pct (ll_info->lt_1024),
+ convert_unsigned_to_pct (ll_info->gt_1024),
+ convert_unsigned_to_pct (ll_info->wself),
+ ll_info->code_addr);
+}
+
+
+/* Output formatted branch mispredict info pointed to by BRM_INFO into
+ the open file FP. */
+
+static void
+output_branch_mispredict_line (FILE *fp,
+ const gcov_pmu_brm_info_t *ll_info)
+{
+ fprintf (fp, "%9s:%5u: count: %u self: %.2f%% addr: "
+ HOST_WIDEST_INT_PRINT_HEX "\n",
+ "PMU BRM",
+ ll_info->line,
+ ll_info->counts,
+ convert_unsigned_to_pct (ll_info->self),
+ ll_info->code_addr);
+}
+
+/* Read in the PMU profile information from the global PMU profile file. */
+
+static void process_pmu_profile (void)
+{
+ unsigned tag;
+ unsigned version;
+ int error = 0;
+ ll_infos_t *ll_infos = &pmu_global_info.ll_infos;
+ brm_infos_t *brm_infos = &pmu_global_info.brm_infos;
+
+ /* Construct path for pmuprofile.gcda filename. */
+ create_file_names (pmu_profile_filename);
+ if (!gcov_open (da_file_name, 1))
+ {
+ fnotice (stderr, "%s:cannot open pmu profile file\n",
+ pmu_profile_filename);
+ return;
+ }
+ if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
+ {
+ fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
+ cleanup:;
+ gcov_close ();
+ return;
+ }
+ version = gcov_read_unsigned ();
+ if (version != GCOV_VERSION)
+ {
+ char v[4], e[4];
+
+ GCOV_UNSIGNED2STRING (v, version);
+ GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
+ fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
+ da_file_name, v, e);
+ }
+ /* read stamp */
+ tag = gcov_read_unsigned ();
+
+ /* Initialize PMU data fields. */
+ ll_infos->ll_count = 0;
+ ll_infos->alloc_ll_count = 64;
+ ll_infos->ll_array = XCNEWVEC (gcov_pmu_ll_info_t *,
+ ll_infos->alloc_ll_count);
+ brm_infos->brm_count = 0;
+ brm_infos->alloc_brm_count = 64;
+ brm_infos->brm_array = XCNEWVEC (gcov_pmu_brm_info_t *,
+ brm_infos->alloc_brm_count);
+
+ while ((tag = gcov_read_unsigned ()))
+ {
+ unsigned length = gcov_read_unsigned ();
+ unsigned long base = gcov_position ();
+
+ if (tag == GCOV_TAG_PMU_LOAD_LATENCY_INFO)
+ {
+ gcov_pmu_ll_info_t *ll_info = XCNEW (gcov_pmu_ll_info_t);
+ gcov_read_pmu_load_latency_info (ll_info, length);
+ ll_infos->ll_count++;
+ if (ll_infos->ll_count >= ll_infos->alloc_ll_count)
+ {
+ /* need to realloc */
+ ll_infos->ll_array = (gcov_pmu_ll_info_t **)
+ xrealloc (ll_infos->ll_array, 2 * ll_infos->alloc_ll_count);
+ if (ll_infos->ll_array == NULL) {
+ fprintf (stderr, "Cannot allocate memory for load latency.\n");
+ goto cleanup;
+ }
+ }
+ ll_infos->ll_array[ll_infos->ll_count - 1] = ll_info;
+ }
+ else if (tag == GCOV_TAG_PMU_BRANCH_MISPREDICT_INFO)
+ {
+ gcov_pmu_brm_info_t *brm_info = XCNEW (gcov_pmu_brm_info_t);
+ gcov_read_pmu_branch_mispredict_info (brm_info, length);
+ brm_infos->brm_count++;
+ if (brm_infos->brm_count >= brm_infos->alloc_brm_count)
+ {
+ /* need to realloc */
+ brm_infos->brm_array = (gcov_pmu_brm_info_t **)
+ xrealloc (brm_infos->brm_array, 2 * brm_infos->alloc_brm_count);
+ if (brm_infos->brm_array == NULL) {
+ fprintf (stderr, "Cannot allocate memory for load latency.\n");
+ goto cleanup;
+ }
+ }
+ brm_infos->brm_array[brm_infos->brm_count - 1] = brm_info;
+ }
+ else if (tag == GCOV_TAG_PMU_TOOL_HEADER)
+ {
+ gcov_pmu_tool_header_t *tool_header = XCNEW (gcov_pmu_tool_header_t);
+ gcov_read_pmu_tool_header (tool_header, length);
+ ll_infos->pmu_tool_header = tool_header;
+ brm_infos->pmu_tool_header = tool_header;
+ }
+
+ gcov_sync (base, length);
+ if ((error = gcov_is_error ()))
+ {
+ fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
+ da_file_name);
+ goto cleanup;
+ }
+ }
+
+ gcov_close ();
+}