gcov: Add __gcov_filename_to_gcfn()
gcc/ * doc/invoke.texi (fprofile-info-section): Mention __gcov_filename_to_gcfn(). Use "freestanding" to match with C11 standard language. Fix minor example code issues. * gcov-io.h (GCOV_FILENAME_MAGIC): Define and document. gcc/testsuite/ * gcc.dg/gcov-info-to-gcda.c: Test __gcov_filename_to_gcfn(). libgcc/ * gcov.h (__gcov_info_to_gcda): Mention __gcov_filename_to_gcfn(). (__gcov_filename_to_gcfn): Declare and document. * libgcov-driver.c (dump_string): New. (__gcov_filename_to_gcfn): Likewise. (__gcov_info_to_gcda): Adjust comment to match C11 standard language.
This commit is contained in:
parent
68a4673fe2
commit
39d80300b3
5 changed files with 105 additions and 30 deletions
|
@ -15462,7 +15462,7 @@ profile information generated by @option{-fprofile-arcs} is placed in the
|
|||
specified section for each translation unit. This option disables the profile
|
||||
information registration through a constructor and it disables the profile
|
||||
information processing through a destructor. This option is not intended to be
|
||||
used in hosted environments such as GNU/Linux. It targets free-standing
|
||||
used in hosted environments such as GNU/Linux. It targets freestanding
|
||||
environments (for example embedded systems) with limited resources which do not
|
||||
support constructors/destructors or the C library file I/O.
|
||||
|
||||
|
@ -15487,14 +15487,8 @@ for example like this:
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern const struct gcov_info *__gcov_info_start[];
|
||||
extern const struct gcov_info *__gcov_info_end[];
|
||||
|
||||
static void
|
||||
filename (const char *f, void *arg)
|
||||
@{
|
||||
puts (f);
|
||||
@}
|
||||
extern const struct gcov_info *const __gcov_info_start[];
|
||||
extern const struct gcov_info *const __gcov_info_end[];
|
||||
|
||||
static void
|
||||
dump (const void *d, unsigned n, void *arg)
|
||||
|
@ -15505,6 +15499,12 @@ dump (const void *d, unsigned n, void *arg)
|
|||
printf ("%02x", c[i]);
|
||||
@}
|
||||
|
||||
static void
|
||||
filename (const char *f, void *arg)
|
||||
@{
|
||||
__gcov_filename_to_gcfn (f, dump, arg );
|
||||
@}
|
||||
|
||||
static void *
|
||||
allocate (unsigned length, void *arg)
|
||||
@{
|
||||
|
@ -15514,8 +15514,8 @@ allocate (unsigned length, void *arg)
|
|||
static void
|
||||
dump_gcov_info (void)
|
||||
@{
|
||||
const struct gcov_info **info = __gcov_info_start;
|
||||
const struct gcov_info **end = __gcov_info_end;
|
||||
const struct gcov_info *const *info = __gcov_info_start;
|
||||
const struct gcov_info *const *end = __gcov_info_end;
|
||||
|
||||
/* Obfuscate variable to prevent compiler optimizations. */
|
||||
__asm__ ("" : "+r" (info));
|
||||
|
@ -15530,9 +15530,9 @@ dump_gcov_info (void)
|
|||
@}
|
||||
|
||||
int
|
||||
main()
|
||||
main (void)
|
||||
@{
|
||||
dump_gcov_info();
|
||||
dump_gcov_info ();
|
||||
return 0;
|
||||
@}
|
||||
@end smallexample
|
||||
|
|
|
@ -60,14 +60,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
|
||||
file : int32:magic int32:version int32:stamp record*
|
||||
|
||||
The magic ident is different for the notes and the data files. The
|
||||
magic ident is used to determine the endianness of the file, when
|
||||
reading. The version is the same for both files and is derived
|
||||
from gcc's version number. The stamp value is used to synchronize
|
||||
note and data files and to synchronize merging within a data
|
||||
file. It need not be an absolute time stamp, merely a ticker that
|
||||
increments fast enough and cycles slow enough to distinguish
|
||||
different compile/run/compile cycles.
|
||||
A filename header may be used to provide a filename for the data in
|
||||
a stream of data to support gcov in freestanding environments. This
|
||||
header is used by the merge-stream subcommand of the gcov-tool. The
|
||||
format of the filename header is
|
||||
|
||||
filename-header : int32:magic int32:version string
|
||||
|
||||
The magic ident is different for the notes and the data files as
|
||||
well as the filename header. The magic ident is used to determine
|
||||
the endianness of the file, when reading. The version is the same
|
||||
for both files and is derived from gcc's version number. The stamp
|
||||
value is used to synchronize note and data files and to synchronize
|
||||
merging within a data file. It need not be an absolute time stamp,
|
||||
merely a ticker that increments fast enough and cycles slow enough
|
||||
to distinguish different compile/run/compile cycles.
|
||||
|
||||
Although the ident and version are formally 32 bit numbers, they
|
||||
are derived from 4 character ASCII strings. The version number
|
||||
|
@ -228,6 +235,7 @@ typedef uint64_t gcov_type_unsigned;
|
|||
/* File magic. Must not be palindromes. */
|
||||
#define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */
|
||||
#define GCOV_NOTE_MAGIC ((gcov_unsigned_t)0x67636e6f) /* "gcno" */
|
||||
#define GCOV_FILENAME_MAGIC ((gcov_unsigned_t)0x6763666e) /* "gcfn" */
|
||||
|
||||
#include "version.h"
|
||||
|
||||
|
|
|
@ -17,16 +17,20 @@ __gcov_info_to_gcda (const struct gcov_info *__info,
|
|||
void *(*__allocate_fn) (unsigned, void *),
|
||||
void *__arg);
|
||||
|
||||
extern void
|
||||
__gcov_filename_to_gcfn (const char *__filename,
|
||||
void (*__dump_fn) (const void *, unsigned, void *),
|
||||
void *__arg);
|
||||
|
||||
extern const struct gcov_info *my_info;
|
||||
|
||||
static unsigned counter;
|
||||
|
||||
static void
|
||||
filename (const char *f, void *arg)
|
||||
{
|
||||
assert (arg == &counter);
|
||||
assert (__builtin_strstr (f, "gcov-info-to-gcda.c") == 0);
|
||||
}
|
||||
static unsigned counter_after_filename;
|
||||
|
||||
static int check_zero;
|
||||
|
||||
static int check_after_filename;
|
||||
|
||||
static void
|
||||
dump (const void *d, unsigned n, void *arg)
|
||||
|
@ -35,14 +39,30 @@ dump (const void *d, unsigned n, void *arg)
|
|||
assert (arg == &counter);
|
||||
|
||||
if (*m == 0)
|
||||
{
|
||||
const unsigned *u = d;
|
||||
assert (*u == 0x6763666e);
|
||||
check_zero = 1;
|
||||
}
|
||||
else if (*m == counter_after_filename)
|
||||
{
|
||||
const unsigned *u = d;
|
||||
assert (*u == 0x67636461);
|
||||
check_after_filename = 1;
|
||||
}
|
||||
|
||||
*m += n;
|
||||
}
|
||||
|
||||
static void
|
||||
filename (const char *f, void *arg)
|
||||
{
|
||||
assert (arg == &counter);
|
||||
assert (__builtin_strstr (f, "gcov-info-to-gcda.c") == 0);
|
||||
__gcov_filename_to_gcfn (f, dump, arg);
|
||||
counter_after_filename = counter;
|
||||
}
|
||||
|
||||
static void *
|
||||
allocate (unsigned length, void *arg)
|
||||
{
|
||||
|
@ -54,6 +74,8 @@ int main()
|
|||
{
|
||||
__asm__ volatile (".set my_info, .LPBX2");
|
||||
__gcov_info_to_gcda (my_info, filename, dump, allocate, &counter);
|
||||
assert (counter > 4);
|
||||
assert (counter > 8);
|
||||
assert (check_zero);
|
||||
assert (check_after_filename);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,8 @@ extern void __gcov_dump (void);
|
|||
stream. The ALLOCATE_FN callback shall allocate memory with a size in
|
||||
characters specified by the first callback parameter. The ARG parameter is
|
||||
a user-provided argument passed as the last argument to the callback
|
||||
functions. */
|
||||
functions. It is recommended to use the __gcov_filename_to_gcfn()
|
||||
in the filename callback function. */
|
||||
|
||||
extern void
|
||||
__gcov_info_to_gcda (const struct gcov_info *__info,
|
||||
|
@ -52,4 +53,18 @@ __gcov_info_to_gcda (const struct gcov_info *__info,
|
|||
void *(*__allocate_fn) (unsigned, void *),
|
||||
void *__arg);
|
||||
|
||||
/* Convert the FILENAME to a gcfn data stream. The DUMP_FN callback is
|
||||
subsequently called with chunks (the begin and length of the chunk are
|
||||
passed as the first two callback parameters) of the gcfn data stream.
|
||||
The ARG parameter is a user-provided argument passed as the last
|
||||
argument to the DUMP_FN callback function. This function is intended
|
||||
to be used by the filename callback of __gcov_info_to_gcda(). The gcfn
|
||||
data stream is used by the merge-stream subcommand of the gcov-tool to
|
||||
get the filename associated with a gcda data stream. */
|
||||
|
||||
extern void
|
||||
__gcov_filename_to_gcfn (const char *__filename,
|
||||
void (*__dump_fn) (const void *, unsigned, void *),
|
||||
void *__arg);
|
||||
|
||||
#endif /* GCC_GCOV_H */
|
||||
|
|
|
@ -410,6 +410,23 @@ dump_counter (gcov_type counter,
|
|||
dump_unsigned (0, dump_fn, arg);
|
||||
}
|
||||
|
||||
/* Dump the STRING using the DUMP handler called with ARG. */
|
||||
|
||||
static inline void
|
||||
dump_string (const char *string,
|
||||
void (*dump_fn) (const void *, unsigned, void *),
|
||||
void *arg)
|
||||
{
|
||||
unsigned length = 0;
|
||||
|
||||
if (string)
|
||||
length = strlen (string) + 1;
|
||||
|
||||
dump_unsigned (length, dump_fn, arg);
|
||||
if (string)
|
||||
(*dump_fn) (string, length, arg);
|
||||
}
|
||||
|
||||
#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
|
||||
|
||||
/* Store all TOP N counters where each has a dynamic length. */
|
||||
|
@ -768,7 +785,7 @@ __gcov_init (struct gcov_info *info)
|
|||
|
||||
#ifdef NEED_L_GCOV_INFO_TO_GCDA
|
||||
/* Convert the gcov info to a gcda data stream. It is intended for
|
||||
free-standing environments which do not support the C library file I/O. */
|
||||
freestanding environments which do not support the C library file I/O. */
|
||||
|
||||
void
|
||||
__gcov_info_to_gcda (const struct gcov_info *gi_ptr,
|
||||
|
@ -780,4 +797,17 @@ __gcov_info_to_gcda (const struct gcov_info *gi_ptr,
|
|||
(*filename_fn) (gi_ptr->filename, arg);
|
||||
write_one_data (gi_ptr, NULL, dump_fn, allocate_fn, arg);
|
||||
}
|
||||
|
||||
/* Convert the filename to a gcfn data stream. It is intended for
|
||||
freestanding environments which do not support the C library file I/O. */
|
||||
|
||||
void
|
||||
__gcov_filename_to_gcfn (const char *filename,
|
||||
void (*dump_fn) (const void *, unsigned, void *),
|
||||
void *arg)
|
||||
{
|
||||
dump_unsigned (GCOV_FILENAME_MAGIC, dump_fn, arg);
|
||||
dump_unsigned (GCOV_VERSION, dump_fn, arg);
|
||||
dump_string (filename, dump_fn, arg);
|
||||
}
|
||||
#endif /* NEED_L_GCOV_INFO_TO_GCDA */
|
||||
|
|
Loading…
Add table
Reference in a new issue