libgcov-driver.c (struct gcov_filename_aux): Rename ...

* libgcov-driver.c (struct gcov_filename_aux): Rename ...
	(struct gcov_filename): ... here.  Include buffer and max length
	fields.
	(gcov_max_filename): Remove.
	(gi_filename): Remove.
	(gcov_exit_compute_summary): Compute max filename here.
	(gcov_exit_merge_gcda): Add filename parm, adjust.
	(gcov_exit_merge_summary): Likewise.
	(gcov_exit_dump_gcov): Adjust for struct gcov_filename changes.
	(gcov_exit): Likewise.
	(__gcov_init): Don't calculate max length here.
	* libgcov_util.c (max_filename_len): Remove.
	(read_gcda_file): Don't calculate max length here.
	(gcov_read_profile_dir): Don't propagate here.
	* libgcov-driver-system.c (alloc_filename_struct): Adjust for
	struct gcov_filename changes.
	(gcov_exit_open_gcda_file): Likewise.

From-SVN: r213092
This commit is contained in:
Nathan Sidwell 2014-07-27 07:22:47 +00:00 committed by Nathan Sidwell
parent 98fa5ef355
commit 6dc33097cc
4 changed files with 113 additions and 121 deletions

View File

@ -1,3 +1,23 @@
2014-07-27 Nathan Sidwell <nathan@acm.org>
* libgcov-driver.c (struct gcov_filename_aux): Rename ...
(struct gcov_filename): ... here. Include buffer and max length
fields.
(gcov_max_filename): Remove.
(gi_filename): Remove.
(gcov_exit_compute_summary): Compute max filename here.
(gcov_exit_merge_gcda): Add filename parm, adjust.
(gcov_exit_merge_summary): Likewise.
(gcov_exit_dump_gcov): Adjust for struct gcov_filename changes.
(gcov_exit): Likewise.
(__gcov_init): Don't calculate max length here.
* libgcov_util.c (max_filename_len): Remove.
(read_gcda_file): Don't calculate max length here.
(gcov_read_profile_dir): Don't propagate here.
* libgcov-driver-system.c (alloc_filename_struct): Adjust for
struct gcov_filename changes.
(gcov_exit_open_gcda_file): Likewise.
2014-07-25 Nathan Sidwell <nathan@acm.org>
* libgcov-driver.c (set_gcov_dump_complete,

View File

@ -83,118 +83,105 @@ create_file_directory (char *filename)
}
static void
allocate_filename_struct (struct gcov_filename_aux *gf)
allocate_filename_struct (struct gcov_filename *gf)
{
const char *gcov_prefix;
int gcov_prefix_strip = 0;
size_t prefix_length;
char *gi_filename_up;
int strip = 0;
gcc_assert (gf);
{
/* Check if the level of dirs to strip off specified. */
char *tmp = getenv("GCOV_PREFIX_STRIP");
if (tmp)
{
gcov_prefix_strip = atoi (tmp);
strip = atoi (tmp);
/* Do not consider negative values. */
if (gcov_prefix_strip < 0)
gcov_prefix_strip = 0;
if (strip < 0)
strip = 0;
}
}
gf->strip = strip;
/* Get file name relocation prefix. Non-absolute values are ignored. */
gcov_prefix = getenv("GCOV_PREFIX");
if (gcov_prefix)
{
prefix_length = strlen(gcov_prefix);
/* Remove an unnecessary trailing '/' */
if (IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
prefix_length--;
}
else
prefix_length = 0;
prefix_length = gcov_prefix ? strlen (gcov_prefix) : 0;
/* Remove an unnecessary trailing '/' */
if (prefix_length && IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
prefix_length--;
/* If no prefix was specified and a prefix stip, then we assume
relative. */
if (gcov_prefix_strip != 0 && prefix_length == 0)
if (!prefix_length && gf->strip)
{
gcov_prefix = ".";
prefix_length = 1;
}
/* Allocate and initialize the filename scratch space plus one. */
gi_filename = (char *) xmalloc (prefix_length + gcov_max_filename + 2);
if (prefix_length)
memcpy (gi_filename, gcov_prefix, prefix_length);
gi_filename_up = gi_filename + prefix_length;
gf->prefix = prefix_length;
gf->gi_filename_up = gi_filename_up;
gf->prefix_length = prefix_length;
gf->gcov_prefix_strip = gcov_prefix_strip;
/* Allocate and initialize the filename scratch space. */
gf->filename = (char *) xmalloc (gf->max_length + prefix_length + 2);
if (prefix_length)
memcpy (gf->filename, gcov_prefix, prefix_length);
}
/* Open a gcda file specified by GI_FILENAME.
Return -1 on error. Return 0 on success. */
static int
gcov_exit_open_gcda_file (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf)
gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
struct gcov_filename *gf)
{
int gcov_prefix_strip;
size_t prefix_length;
char *gi_filename_up;
const char *fname, *s;
const char *fname = gi_ptr->filename;
char *dst = gf->filename + gf->prefix;
gcov_prefix_strip = gf->gcov_prefix_strip;
gi_filename_up = gf->gi_filename_up;
prefix_length = gf->prefix_length;
fname = gi_ptr->filename;
/* Avoid to add multiple drive letters into combined path. */
if (prefix_length != 0 && HAS_DRIVE_SPEC(fname))
fname += 2;
/* Build relocated filename, stripping off leading
directories from the initial filename if requested. */
if (gcov_prefix_strip > 0)
if (gf->strip > 0)
{
int level = 0;
const char *probe = fname;
int level;
s = fname;
if (IS_DIR_SEPARATOR(*s))
++s;
/* Remove a leading separator, without counting it. */
if (IS_DIR_SEPARATOR (*probe))
probe++;
/* Skip selected directory levels. */
for (; (*s != '\0') && (level < gcov_prefix_strip); s++)
if (IS_DIR_SEPARATOR(*s))
/* Skip selected directory levels. If we fall off the end, we
keep the final part. */
for (level = gf->strip; *probe && level; probe++)
if (IS_DIR_SEPARATOR (*probe))
{
fname = s;
level++;
fname = probe;
level--;
}
}
/* Update complete filename with stripped original. */
if (prefix_length != 0 && !IS_DIR_SEPARATOR (*fname))
if (gf->prefix)
{
/* If prefix is given, add directory separator. */
strcpy (gi_filename_up, "/");
strcpy (gi_filename_up + 1, fname);
}
else
strcpy (gi_filename_up, fname);
/* Avoid to add multiple drive letters into combined path. */
if (HAS_DRIVE_SPEC(fname))
fname += 2;
if (!gcov_open (gi_filename))
if (!IS_DIR_SEPARATOR (*fname))
*dst++ = '/';
}
strcpy (dst, fname);
if (!gcov_open (gf->filename))
{
/* Open failed likely due to missed directory.
Create directory and retry to open file. */
if (create_file_directory (gi_filename))
if (create_file_directory (gf->filename))
{
fprintf (stderr, "profiling:%s:Skip\n", gi_filename);
fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
return -1;
}
if (!gcov_open (gi_filename))
if (!gcov_open (gf->filename))
{
fprintf (stderr, "profiling:%s:Cannot open\n", gi_filename);
fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
return -1;
}
}

View File

@ -66,6 +66,17 @@ struct gcov_summary_buffer
struct gcov_summary summary;
};
/* A struct that bundles all the related information about the
gcda filename. */
struct gcov_filename
{
char *filename; /* filename buffer */
size_t max_length; /* maximum filename length */
int strip; /* leading chars to strip from filename */
size_t prefix; /* chars to prepend to filename */
};
/* Chain of per-object gcov structures. */
#ifndef IN_GCOV_TOOL
/* We need to expose this static variable when compiling for gcov-tool. */
@ -73,13 +84,6 @@ static
#endif
struct gcov_info *gcov_list;
/* Size of the longest file name. */
/* We need to expose this static variable when compiling for gcov-tool. */
#ifndef IN_GCOV_TOOL
static
#endif
size_t gcov_max_filename = 0;
/* Flag when the profile has already been dumped via __gcov_dump(). */
static int gcov_dump_complete;
@ -275,8 +279,6 @@ gcov_compute_histogram (struct gcov_summary *sum)
}
}
/* gcda filename. */
static char *gi_filename;
/* buffer for the fn_data from another program. */
static struct gcov_fn_buffer *fn_buffer;
/* buffer for summary from other programs to be written out. */
@ -286,11 +288,13 @@ static struct gcov_summary_buffer *sum_buffer;
functions executed once may mistakely become cold. */
static int run_accounted = 0;
/* This funtions computes the program level summary and the histo-gram.
It computes and returns CRC32 and stored summary in THIS_PRG. */
/* This function computes the program level summary and the histo-gram.
It computes and returns CRC32 and stored summary in THIS_PRG.
Also determines the longest filename length of the info files. */
static gcov_unsigned_t
gcov_exit_compute_summary (struct gcov_summary *this_prg)
gcov_exit_compute_summary (struct gcov_summary *this_prg,
size_t *max_length)
{
struct gcov_info *gi_ptr;
const struct gcov_fn_info *gfi_ptr;
@ -303,8 +307,13 @@ gcov_exit_compute_summary (struct gcov_summary *this_prg)
/* Find the totals for this execution. */
memset (this_prg, 0, sizeof (*this_prg));
*max_length = 0;
for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
{
size_t len = strlen (gi_ptr->filename);
if (len > *max_length)
*max_length = len;
crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
@ -345,14 +354,6 @@ gcov_exit_compute_summary (struct gcov_summary *this_prg)
return crc32;
}
/* A struct that bundles all the related information about the
gcda filename. */
struct gcov_filename_aux{
char *gi_filename_up;
int gcov_prefix_strip;
size_t prefix_length;
};
/* Including system dependent components. */
#include "libgcov-driver-system.c"
@ -361,7 +362,8 @@ struct gcov_filename_aux{
Return -1 on error. In this case, caller will goto read_fatal. */
static int
gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
gcov_exit_merge_gcda (const char *filename,
struct gcov_info *gi_ptr,
struct gcov_summary *prg_p,
struct gcov_summary *this_prg,
gcov_position_t *summary_pos_p,
@ -376,7 +378,7 @@ gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
struct gcov_summary_buffer **sum_tail = &sum_buffer;
length = gcov_read_unsigned ();
if (!gcov_version (gi_ptr, length, gi_filename))
if (!gcov_version (gi_ptr, length, filename))
return -1;
length = gcov_read_unsigned ();
@ -451,8 +453,7 @@ gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
it back out -- we'll be inserting data before
this point, so cannot simply keep the data in the
file. */
fn_tail = buffer_fn_data (gi_filename,
gi_ptr, fn_tail, f_ix);
fn_tail = buffer_fn_data (filename, gi_ptr, fn_tail, f_ix);
if (!fn_tail)
goto read_mismatch;
continue;
@ -494,14 +495,14 @@ gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
{
read_mismatch:;
gcov_error ("profiling:%s:Merge mismatch for %s %u\n",
gi_filename, f_ix >= 0 ? "function" : "summary",
filename, f_ix >= 0 ? "function" : "summary",
f_ix < 0 ? -1 - f_ix : f_ix);
return -1;
}
return 0;
read_error:
gcov_error ("profiling:%s:%s merging\n", gi_filename,
gcov_error ("profiling:%s:%s merging\n", filename,
error < 0 ? "Overflow": "Error");
return -1;
}
@ -606,7 +607,8 @@ gcov_exit_write_gcda (const struct gcov_info *gi_ptr,
Return -1 on error. Return 0 on success. */
static int
gcov_exit_merge_summary (const struct gcov_info *gi_ptr, struct gcov_summary *prg,
gcov_exit_merge_summary (const char *filename,
const struct gcov_info *gi_ptr, struct gcov_summary *prg,
struct gcov_summary *this_prg, gcov_unsigned_t crc32,
struct gcov_summary *all_prg __attribute__ ((unused)))
{
@ -644,7 +646,7 @@ gcov_exit_merge_summary (const struct gcov_info *gi_ptr, struct gcov_summary *pr
else if (cs_prg->runs)
{
gcov_error ("profiling:%s:Merge mismatch for summary.\n",
gi_filename);
filename);
return -1;
}
#if !GCOV_LOCKED
@ -670,7 +672,7 @@ gcov_exit_merge_summary (const struct gcov_info *gi_ptr, struct gcov_summary *pr
{
gcov_error ("profiling:%s:Data file mismatch - some "
"data files may have been concurrently "
"updated without locking support\n", gi_filename);
"updated without locking support\n", filename);
all_prg->checksum = ~0u;
}
#endif
@ -689,7 +691,7 @@ gcov_exit_merge_summary (const struct gcov_info *gi_ptr, struct gcov_summary *pr
summaries separate. */
static void
gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf,
gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
gcov_unsigned_t crc32, struct gcov_summary *all_prg,
struct gcov_summary *this_prg)
{
@ -712,11 +714,11 @@ gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf,
/* Merge data from file. */
if (tag != GCOV_DATA_MAGIC)
{
gcov_error ("profiling:%s:Not a gcov data file\n", gi_filename);
gcov_error ("profiling:%s:Not a gcov data file\n", gf->filename);
goto read_fatal;
}
error = gcov_exit_merge_gcda (gi_ptr, &prg, this_prg, &summary_pos, &eof_pos,
crc32);
error = gcov_exit_merge_gcda (gf->filename, gi_ptr, &prg, this_prg,
&summary_pos, &eof_pos, crc32);
if (error == -1)
goto read_fatal;
}
@ -729,7 +731,8 @@ gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf,
summary_pos = eof_pos;
}
error = gcov_exit_merge_summary (gi_ptr, &prg, this_prg, crc32, all_prg);
error = gcov_exit_merge_summary (gf->filename, gi_ptr, &prg, this_prg,
crc32, all_prg);
if (error == -1)
goto read_fatal;
@ -744,7 +747,7 @@ read_fatal:;
gcov_error (error < 0 ?
"profiling:%s:Overflow writing\n" :
"profiling:%s:Error writing\n",
gi_filename);
gf->filename);
}
@ -756,7 +759,7 @@ void
gcov_exit (void)
{
struct gcov_info *gi_ptr;
struct gcov_filename_aux gf;
struct gcov_filename gf;
gcov_unsigned_t crc32;
struct gcov_summary all_prg;
struct gcov_summary this_prg;
@ -767,8 +770,8 @@ gcov_exit (void)
return;
gcov_dump_complete = 1;
crc32 = gcov_exit_compute_summary (&this_prg);
crc32 = gcov_exit_compute_summary (&this_prg, &gf.max_length);
allocate_filename_struct (&gf);
#if !GCOV_LOCKED
@ -780,8 +783,7 @@ gcov_exit (void)
gcov_exit_dump_gcov (gi_ptr, &gf, crc32, &all_prg, &this_prg);
run_accounted = 1;
if (gi_filename)
free (gi_filename);
free (gf.filename);
}
/* Reset all counters to zero. */
@ -826,12 +828,6 @@ __gcov_init (struct gcov_info *info)
return;
if (gcov_version (info, info->version, 0))
{
size_t filename_length = strlen(info->filename);
/* Refresh the longest file name information */
if (filename_length > gcov_max_filename)
gcov_max_filename = filename_length;
if (!gcov_list)
atexit (gcov_exit);

View File

@ -38,7 +38,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
extern gcov_position_t gcov_position();
extern int gcov_is_error();
extern size_t gcov_max_filename;
/* Verbose mode for debug. */
static int verbose;
@ -78,8 +77,6 @@ static int k_ctrs_mask[GCOV_COUNTERS];
static struct gcov_ctr_info k_ctrs[GCOV_COUNTERS];
/* Number of kind of counters that have been seen. */
static int k_ctrs_types;
/* The longest length of all the filenames. */
static int max_filename_len;
/* Merge functions for counters. */
#define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) __gcov_merge ## FN_TYPE,
@ -301,13 +298,11 @@ read_gcda_file (const char *filename)
num_fn_info = 0;
curr_fn_info = 0;
{
char *str_dup = (char*) xmalloc (strlen (filename) + 1);
int len;
size_t len = strlen (filename) + 1;
char *str_dup = (char*) xmalloc (len);
strcpy (str_dup, filename);
memcpy (str_dup, filename, len);
obj_info->filename = str_dup;
if ((len = strlen (filename)) > max_filename_len)
max_filename_len = len;
}
/* Read stamp. */
@ -433,8 +428,7 @@ read_profile_dir_init (void)
/* Driver for read a profile directory and convert into gcov_info list in memory.
Return NULL on error,
Return the head of gcov_info list on success.
Note the file static variable GCOV_MAX_FILENAME is also set. */
Return the head of gcov_info list on success. */
struct gcov_info *
gcov_read_profile_dir (const char* dir_name, int recompute_summary ATTRIBUTE_UNUSED)
@ -462,11 +456,6 @@ gcov_read_profile_dir (const char* dir_name, int recompute_summary ATTRIBUTE_UNU
free (pwd);
/* gcov_max_filename is defined in libgcov.c that records the
max filename len. We need to set it here to allocate the
array for dumping. */
gcov_max_filename = max_filename_len;
return gcov_info_head;;
}