* [PATCH v3] gcov: Add __gcov_info_to_gdca()
@ 2021-07-23 9:39 Sebastian Huber
2021-08-05 12:53 ` Martin Liška
0 siblings, 1 reply; 8+ messages in thread
From: Sebastian Huber @ 2021-07-23 9:39 UTC (permalink / raw)
To: gcc-patches
Add __gcov_info_to_gcda() to libgcov to get the gcda data for a gcda info in a
freestanding environment. It is intended to be used with the
-fprofile-info-section option. A crude test program which doesn't use a linker
script is (use "gcc -coverage -fprofile-info-section -lgcc test.c" to compile
it):
#include <gcov.h>
#include <stdio.h>
#include <stdlib.h>
extern const struct gcov_info *my_info;
static void
filename (const char *f, void *arg)
{
printf("filename: %s\n", f);
}
static void
dump (const void *d, unsigned n, void *arg)
{
const unsigned char *c = d;
for (unsigned i = 0; i < n; ++i)
printf ("%02x", c[i]);
}
static void *
allocate (unsigned length, void *arg)
{
return malloc (length);
}
int main()
{
__asm__ volatile (".set my_info, .LPBX2");
__gcov_info_to_gcda (my_info, filename, dump, allocate, NULL);
return 0;
}
With this patch, <stdint.h> is included in libgcov-driver.c even if
inhibit_libc is defined. This header file should be also available for
freestanding environments. If this is not the case, then we have to define
intptr_t somehow.
The patch removes one use of memset() which makes the <string.h> include
superfluous.
gcc/
* gcov-io.h (gcov_write): Declare.
* gcov-io.c (gcov_write): New.
(gcov_write_counter): Remove.
(gcov_write_tag_length): Likewise.
(gcov_write_summary): Replace gcov_write_tag_length() with calls to
gcov_write_unsigned().
* doc/invoke.texi (fprofile-info-section): Mention
__gcov_info_to_gdca().
gcc/testsuite/
* gcc.dg/gcov-info-to-gcda.c: New test.
libgcc/
* Makefile.in (LIBGCOV_DRIVER): Add _gcov_info_to_gcda.
* gcov.h (gcov_info): Declare.
(__gcov_info_to_gdca): Likewise.
* libgcov.h (gcov_write_counter): Remove.
(gcov_write_tag_length): Likewise.
* libgcov-driver.c (#include <stdint.h>): New.
(#include <string.h>): Remove.
(NEED_L_GCOV): Conditionally define.
(NEED_L_GCOV_INFO_TO_GCDA): Likewise.
(are_all_counters_zero): New.
(gcov_dump_handler): Likewise.
(gcov_allocate_handler): Likewise.
(dump_unsigned): Likewise.
(dump_counter): Likewise.
(write_topn_counters): Add dump_fn, allocate_fn, and arg parameters.
Use dump_unsigned() and dump_counter().
(write_one_data): Add dump_fn, allocate_fn, and arg parameters. Use
dump_unsigned(), dump_counter(), and are_all_counters_zero().
(__gcov_info_to_gcda): New.
---
gcc/doc/invoke.texi | 80 +++++++--
gcc/gcov-io.c | 36 ++---
gcc/gcov-io.h | 1 +
gcc/testsuite/gcc.dg/gcov-info-to-gcda.c | 60 +++++++
libgcc/Makefile.in | 2 +-
libgcc/gcov.h | 19 +++
libgcc/libgcov-driver.c | 196 ++++++++++++++++++-----
libgcc/libgcov.h | 5 -
8 files changed, 313 insertions(+), 86 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/gcov-info-to-gcda.c
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 32697e6117c0..5f31312b9485 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -14798,17 +14798,17 @@ To optimize the program based on the collected profile information, use
Register the profile information in the specified section instead of using a
constructor/destructor. The section name is @var{name} if it is specified,
otherwise the section name defaults to @code{.gcov_info}. A pointer to the
-profile information generated by @option{-fprofile-arcs} or
-@option{-ftest-coverage} 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 systems with limited resources
-which do not support constructors and destructors. The linker could collect
-the input sections in a continuous memory block and define start and end
-symbols. The runtime support could dump the profiling information registered
-in this linker set during program termination to a serial line for example. A
-GNU linker script example which defines a linker output section follows:
+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
+environments (for example embedded systems) with limited resources which do not
+support constructors/destructors or the C library file I/O.
+
+The linker could collect the input sections in a continuous memory block and
+define start and end symbols. A GNU linker script example which defines a
+linker output section follows:
@smallexample
.gcov_info :
@@ -14819,6 +14819,64 @@ GNU linker script example which defines a linker output section follows:
@}
@end smallexample
+The program could dump the profiling information registered in this linker set
+for example like this:
+
+@smallexample
+#include <gcov.h>
+#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);
+@}
+
+static void
+dump (const void *d, unsigned n, void *arg)
+@{
+ const unsigned char *c = d;
+
+ for (unsigned i = 0; i < n; ++i)
+ printf ("%02x", c[i]);
+@}
+
+static void *
+allocate (unsigned length, void *arg)
+@{
+ return malloc (length);
+@}
+
+static void
+dump_gcov_info (void)
+@{
+ const struct gcov_info **info = __gcov_info_start;
+ const struct gcov_info **end = __gcov_info_end;
+
+ /* Obfuscate variable to prevent compiler optimizations. */
+ __asm__ ("" : "+r" (end));
+
+ while (info != end)
+ @{
+ void *arg = NULL;
+ __gcov_info_to_gcda (*info, filename, dump, allocate, arg);
+ putchar ('\n');
+ ++info;
+ @}
+@}
+
+int
+main()
+@{
+ dump_gcov_info();
+ return 0;
+@}
+@end smallexample
+
@item -fprofile-note=@var{path}
@opindex fprofile-note
diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c
index 4b1e11d45305..864c01f04a97 100644
--- a/gcc/gcov-io.c
+++ b/gcc/gcov-io.c
@@ -227,30 +227,25 @@ gcov_magic (gcov_unsigned_t magic, gcov_unsigned_t expected)
#endif
#if !IN_GCOV
-/* Write unsigned VALUE to coverage file. */
+/* Write DATA of LENGTH characters to coverage file. */
GCOV_LINKAGE void
-gcov_write_unsigned (gcov_unsigned_t value)
+gcov_write (const void *data, unsigned length)
{
- gcov_unsigned_t r = fwrite (&value, sizeof (value), 1, gcov_var.file);
+ gcov_unsigned_t r = fwrite (data, length, 1, gcov_var.file);
if (r != 1)
gcov_var.error = 1;
}
-/* Write counter VALUE to coverage file. Sets error flag
- appropriately. */
+/* Write unsigned VALUE to coverage file. */
-#if IN_LIBGCOV
GCOV_LINKAGE void
-gcov_write_counter (gcov_type value)
+gcov_write_unsigned (gcov_unsigned_t value)
{
- gcov_write_unsigned ((gcov_unsigned_t) value);
- if (sizeof (value) > sizeof (gcov_unsigned_t))
- gcov_write_unsigned ((gcov_unsigned_t) (value >> 32));
- else
- gcov_write_unsigned (0);
+ gcov_unsigned_t r = fwrite (&value, sizeof (value), 1, gcov_var.file);
+ if (r != 1)
+ gcov_var.error = 1;
}
-#endif /* IN_LIBGCOV */
#if !IN_LIBGCOV
/* Write STRING to coverage file. Sets error flag on file
@@ -347,22 +342,13 @@ gcov_write_length (gcov_position_t position)
#else /* IN_LIBGCOV */
-/* Write a tag TAG and length LENGTH. */
-
-GCOV_LINKAGE void
-gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length)
-{
- gcov_write_unsigned (tag);
- gcov_write_unsigned (length);
-}
-
-/* Write a summary structure to the gcov file. Return nonzero on
- overflow. */
+/* Write a summary structure to the gcov file. */
GCOV_LINKAGE void
gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary)
{
- gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH);
+ gcov_write_unsigned (tag);
+ gcov_write_unsigned (GCOV_TAG_SUMMARY_LENGTH);
gcov_write_unsigned (summary->runs);
gcov_write_unsigned (summary->sum_max);
}
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 538bee81263a..99e1964c1094 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -367,6 +367,7 @@ char *mangle_path (char const *base);
#if !IN_GCOV
/* Available outside gcov */
+GCOV_LINKAGE void gcov_write (const void *, unsigned) ATTRIBUTE_HIDDEN;
GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t) ATTRIBUTE_HIDDEN;
#endif
diff --git a/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c b/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c
new file mode 100644
index 000000000000..390f377de4fe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c
@@ -0,0 +1,60 @@
+/* { dg-do run } */
+/* { dg-skip-if "profile-info-section" { powerpc-ibm-aix* } } */
+/* { dg-options "-fprofile-arcs -fprofile-info-section" } */
+
+#define assert(expr) \
+ ((expr) \
+ ? (void)0 \
+ : (__builtin_printf ("%s:%i: Assertion `%s' failed.\n", \
+ __FILE__, __LINE__, #expr), \
+ __builtin_abort ()))
+
+struct gcov_info;
+
+extern void
+__gcov_info_to_gcda (const struct gcov_info *__info,
+ void (*__filename_fn) (const char *, void *),
+ void (*__dump_fn) (const void *, unsigned, void *),
+ void *(*__allocate_fn) (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 void
+dump (const void *d, unsigned n, void *arg)
+{
+ unsigned *m = (unsigned *)arg;
+ assert (arg == &counter);
+
+ if (*m == 0)
+ {
+ const unsigned *u = d;
+ assert (*u == 0x67636461);
+ }
+
+ *m += n;
+}
+
+static void *
+allocate (unsigned length, void *arg)
+{
+ assert (arg == &counter);
+ return __builtin_malloc (length);
+}
+
+int main()
+{
+ __asm__ volatile (".set my_info, .LPBX2");
+ __gcov_info_to_gcda (my_info, filename, dump, allocate, &counter);
+ assert (counter > 4);
+ return 0;
+}
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 2c8be561eb53..7ec975845544 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -908,7 +908,7 @@ LIBGCOV_INTERFACE = _gcov_dump _gcov_fork \
_gcov_execl _gcov_execlp \
_gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset \
_gcov_lock_unlock
-LIBGCOV_DRIVER = _gcov
+LIBGCOV_DRIVER = _gcov _gcov_info_to_gcda
libgcov-merge-objects = $(patsubst %,%$(objext),$(LIBGCOV_MERGE))
libgcov-profiler-objects = $(patsubst %,%$(objext),$(LIBGCOV_PROFILER))
diff --git a/libgcc/gcov.h b/libgcc/gcov.h
index e6492cdd31ea..66d03bf4e5d4 100644
--- a/libgcc/gcov.h
+++ b/libgcc/gcov.h
@@ -25,6 +25,8 @@
#ifndef GCC_GCOV_H
#define GCC_GCOV_H
+struct gcov_info;
+
/* Set all counters to zero. */
extern void __gcov_reset (void);
@@ -33,4 +35,21 @@ extern void __gcov_reset (void);
extern void __gcov_dump (void);
+/* Convert the gcov information referenced by INFO to a gcda data stream.
+ The FILENAME_FN callback is called exactly once with the filename associated
+ with the gcov information. The filename may be NULL. Afterwards, 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 gcda data
+ 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. */
+
+extern void
+__gcov_info_to_gcda (const struct gcov_info *__info,
+ void (*__filename_fn) (const char *, void *),
+ void (*__dump_fn) (const void *, unsigned, void *),
+ void *(*__allocate_fn) (unsigned, void *),
+ void *__arg);
+
#endif /* GCC_GCOV_H */
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index df7ccb235677..32e312ec3cfa 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -26,6 +26,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "libgcov.h"
#include "gcov-io.h"
+#include <stdint.h>
+
+/* Return 1, if all counter values are zero, otherwise 0. */
+
+static inline int
+are_all_counters_zero (const struct gcov_ctr_info *ci_ptr)
+{
+ for (unsigned i = 0; i < ci_ptr->num; i++)
+ if (ci_ptr->values[i] != 0)
+ return 0;
+
+ return 1;
+}
+
#if defined(inhibit_libc)
/* If libc and its header files are not available, provide dummy functions. */
@@ -35,8 +49,6 @@ void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
#else /* inhibit_libc */
-#include <string.h>
-
#if GCOV_LOCKED
#include <fcntl.h>
#include <errno.h>
@@ -51,8 +63,17 @@ void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
#include <sys/mman.h>
#endif
-#ifdef L_gcov
+#endif /* inhibit_libc */
+
+#if defined(L_gcov) && !defined(inhibit_libc)
+#define NEED_L_GCOV
+#endif
+#if defined(L_gcov_info_to_gcda) && !IN_GCOV_TOOL
+#define NEED_L_GCOV_INFO_TO_GCDA
+#endif
+
+#ifdef NEED_L_GCOV
/* A utility function for outputting errors. */
static int gcov_error (const char *, ...);
@@ -343,6 +364,51 @@ read_error:
return -1;
}
+/* Write the DATA of LENGTH characters to the gcov file. */
+
+static void
+gcov_dump_handler (const void *data,
+ unsigned length,
+ void *arg ATTRIBUTE_UNUSED)
+{
+ gcov_write (data, length);
+}
+
+/* Allocate SIZE characters and return the address of the allocated memory. */
+
+static void *
+gcov_allocate_handler (unsigned size, void *arg ATTRIBUTE_UNUSED)
+{
+ return xmalloc (size);
+}
+#endif /* NEED_L_GCOV */
+
+#if defined(NEED_L_GCOV) || defined(NEED_L_GCOV_INFO_TO_GCDA)
+/* Dump the WORD using the DUMP handler called with ARG. */
+
+static inline void
+dump_unsigned (gcov_unsigned_t word,
+ void (*dump_fn) (const void *, unsigned, void *),
+ void *arg)
+{
+ (*dump_fn) (&word, sizeof (word), arg);
+}
+
+/* Dump the COUNTER using the DUMP handler called with ARG. */
+
+static inline void
+dump_counter (gcov_type counter,
+ void (*dump_fn) (const void *, unsigned, void *),
+ void *arg)
+{
+ dump_unsigned ((gcov_unsigned_t)counter, dump_fn, arg);
+
+ if (sizeof (counter) > sizeof (gcov_unsigned_t))
+ dump_unsigned ((gcov_unsigned_t)(counter >> 32), dump_fn, arg);
+ else
+ dump_unsigned (0, dump_fn, arg);
+}
+
#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
/* Store all TOP N counters where each has a dynamic length. */
@@ -350,7 +416,10 @@ read_error:
static void
write_topn_counters (const struct gcov_ctr_info *ci_ptr,
unsigned t_ix,
- gcov_unsigned_t n_counts)
+ gcov_unsigned_t n_counts,
+ void (*dump_fn) (const void *, unsigned, void *),
+ void *(*allocate_fn)(unsigned, void *),
+ void *arg)
{
unsigned counters = n_counts / GCOV_TOPN_MEM_COUNTERS;
gcc_assert (n_counts % GCOV_TOPN_MEM_COUNTERS == 0);
@@ -365,46 +434,49 @@ write_topn_counters (const struct gcov_ctr_info *ci_ptr,
if (list_sizes == NULL || counters > list_size_length)
{
list_size_length = MAX (LIST_SIZE_MIN_LENGTH, 2 * counters);
-#if HAVE_SYS_MMAN_H
+#if !defined(inhibit_libc) && HAVE_SYS_MMAN_H
list_sizes
= (unsigned *)malloc_mmap (list_size_length * sizeof (unsigned));
#endif
/* Malloc fallback. */
if (list_sizes == NULL)
- list_sizes = (unsigned *)xmalloc (list_size_length * sizeof (unsigned));
+ list_sizes =
+ (unsigned *)(*allocate_fn) (list_size_length * sizeof (unsigned),
+ arg);
}
- memset (list_sizes, 0, counters * sizeof (unsigned));
unsigned pair_total = 0;
for (unsigned i = 0; i < counters; i++)
{
gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2];
+ unsigned sizes = 0;
+
for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start;
node != NULL; node = node->next)
- {
- ++pair_total;
- ++list_sizes[i];
- }
+ ++sizes;
+
+ pair_total += sizes;
+ list_sizes[i] = sizes;
}
unsigned disk_size = GCOV_TOPN_DISK_COUNTERS * counters + 2 * pair_total;
- gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
- GCOV_TAG_COUNTER_LENGTH (disk_size));
+ dump_unsigned (GCOV_TAG_FOR_COUNTER (t_ix), dump_fn, arg),
+ dump_unsigned (GCOV_TAG_COUNTER_LENGTH (disk_size), dump_fn, arg);
for (unsigned i = 0; i < counters; i++)
{
- gcov_write_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i]);
- gcov_write_counter (list_sizes[i]);
+ dump_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i], dump_fn, arg);
+ dump_counter (list_sizes[i], dump_fn, arg);
gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2];
unsigned j = 0;
for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start;
j < list_sizes[i]; node = node->next, j++)
{
- gcov_write_counter (node->value);
- gcov_write_counter (node->count);
+ dump_counter (node->value, dump_fn, arg);
+ dump_counter (node->count, dump_fn, arg);
}
}
}
@@ -415,25 +487,36 @@ write_topn_counters (const struct gcov_ctr_info *ci_ptr,
static void
write_one_data (const struct gcov_info *gi_ptr,
- const struct gcov_summary *prg_p)
+ const struct gcov_summary *prg_p,
+ void (*dump_fn) (const void *, unsigned, void *),
+ void *(*allocate_fn) (unsigned, void *),
+ void *arg)
{
unsigned f_ix;
- gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
- gcov_write_unsigned (gi_ptr->stamp);
+ dump_unsigned (GCOV_DATA_MAGIC, dump_fn, arg);
+ dump_unsigned (GCOV_VERSION, dump_fn, arg);
+ dump_unsigned (gi_ptr->stamp, dump_fn, arg);
+#ifdef NEED_L_GCOV
/* Generate whole program statistics. */
gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, prg_p);
+#else
+ (void)prg_p;
+#endif
/* Write execution counts for each function. */
for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
{
+#ifdef NEED_L_GCOV
unsigned buffered = 0;
+#endif
const struct gcov_fn_info *gfi_ptr;
const struct gcov_ctr_info *ci_ptr;
gcov_unsigned_t length;
unsigned t_ix;
+#ifdef NEED_L_GCOV
if (fn_buffer && fn_buffer->fn_ix == f_ix)
{
/* Buffered data from another program. */
@@ -442,6 +525,7 @@ write_one_data (const struct gcov_info *gi_ptr,
length = GCOV_TAG_FUNCTION_LENGTH;
}
else
+#endif
{
gfi_ptr = gi_ptr->functions[f_ix];
if (gfi_ptr && gfi_ptr->key == gi_ptr)
@@ -450,13 +534,14 @@ write_one_data (const struct gcov_info *gi_ptr,
length = 0;
}
- gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
+ dump_unsigned (GCOV_TAG_FUNCTION, dump_fn, arg);
+ dump_unsigned (length, dump_fn, arg);
if (!length)
continue;
- gcov_write_unsigned (gfi_ptr->ident);
- gcov_write_unsigned (gfi_ptr->lineno_checksum);
- gcov_write_unsigned (gfi_ptr->cfg_checksum);
+ dump_unsigned (gfi_ptr->ident, dump_fn, arg);
+ dump_unsigned (gfi_ptr->lineno_checksum, dump_fn, arg);
+ dump_unsigned (gfi_ptr->cfg_checksum, dump_fn, arg);
ci_ptr = gfi_ptr->ctrs;
for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
@@ -469,39 +554,43 @@ write_one_data (const struct gcov_info *gi_ptr,
n_counts = ci_ptr->num;
if (t_ix == GCOV_COUNTER_V_TOPN || t_ix == GCOV_COUNTER_V_INDIR)
- write_topn_counters (ci_ptr, t_ix, n_counts);
+ write_topn_counters (ci_ptr,
+ t_ix,
+ n_counts,
+ dump_fn,
+ allocate_fn,
+ arg);
else
{
- /* Do not stream when all counters are zero. */
- int all_zeros = 1;
- for (unsigned i = 0; i < n_counts; i++)
- if (ci_ptr->values[i] != 0)
- {
- all_zeros = 0;
- break;
- }
-
- if (all_zeros)
- gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
- GCOV_TAG_COUNTER_LENGTH (-n_counts));
+ dump_unsigned (GCOV_TAG_FOR_COUNTER (t_ix), dump_fn, arg);
+ if (are_all_counters_zero (ci_ptr))
+ /* Do not stream when all counters are zero. */
+ dump_unsigned (GCOV_TAG_COUNTER_LENGTH (-n_counts),
+ dump_fn,
+ arg);
else
{
- gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
- GCOV_TAG_COUNTER_LENGTH (n_counts));
+ dump_unsigned (GCOV_TAG_COUNTER_LENGTH (n_counts),
+ dump_fn,
+ arg);
for (unsigned i = 0; i < n_counts; i++)
- gcov_write_counter (ci_ptr->values[i]);
+ dump_counter (ci_ptr->values[i], dump_fn, arg);
}
}
ci_ptr++;
}
+#ifdef NEED_L_GCOV
if (buffered)
fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
+#endif
}
- gcov_write_unsigned (0);
+ dump_unsigned (0, dump_fn, arg);
}
+#endif /* NEED_L_GCOV || NEED_L_GCOV_INFO_TO_GCDA */
+#ifdef NEED_L_GCOV
/* Dump the coverage counts for one gcov_info object. 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
@@ -550,7 +639,11 @@ dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
summary = gi_ptr->summary;
#endif
- write_one_data (gi_ptr, &summary);
+ write_one_data (gi_ptr,
+ &summary,
+ gcov_dump_handler,
+ gcov_allocate_handler,
+ NULL);
/* fall through */
read_fatal:;
@@ -680,5 +773,20 @@ __gcov_init (struct gcov_info *info)
}
}
#endif /* !IN_GCOV_TOOL */
-#endif /* L_gcov */
-#endif /* inhibit_libc */
+#endif /* NEED_L_GCOV */
+
+#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. */
+
+void
+__gcov_info_to_gcda (const struct gcov_info *gi_ptr,
+ void (*filename_fn) (const char *, void *),
+ void (*dump_fn) (const void *, unsigned, void *),
+ void *(*allocate_fn) (unsigned, void *),
+ void *arg)
+{
+ (*filename_fn) (gi_ptr->filename, arg);
+ write_one_data (gi_ptr, NULL, dump_fn, allocate_fn, arg);
+}
+#endif /* NEED_L_GCOV_INFO_TO_GCDA */
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 8d323db05386..9c537253293f 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -114,13 +114,11 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
#define gcov_var __gcov_var
#define gcov_open __gcov_open
#define gcov_close __gcov_close
-#define gcov_write_tag_length __gcov_write_tag_length
#define gcov_position __gcov_position
#define gcov_seek __gcov_seek
#define gcov_rewrite __gcov_rewrite
#define gcov_is_error __gcov_is_error
#define gcov_write_unsigned __gcov_write_unsigned
-#define gcov_write_counter __gcov_write_counter
#define gcov_write_summary __gcov_write_summary
#define gcov_read_unsigned __gcov_read_unsigned
#define gcov_read_counter __gcov_read_counter
@@ -345,9 +343,6 @@ extern int __gcov_execve (const char *, char *const [], char *const [])
/* Functions that only available in libgcov. */
GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_write_counter (gcov_type) ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t)
- ATTRIBUTE_HIDDEN;
GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
const struct gcov_summary *)
ATTRIBUTE_HIDDEN;
--
2.26.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] gcov: Add __gcov_info_to_gdca()
2021-07-23 9:39 [PATCH v3] gcov: Add __gcov_info_to_gdca() Sebastian Huber
@ 2021-08-05 12:53 ` Martin Liška
2021-08-06 5:31 ` Sebastian Huber
0 siblings, 1 reply; 8+ messages in thread
From: Martin Liška @ 2021-08-05 12:53 UTC (permalink / raw)
To: Sebastian Huber, gcc-patches
On 7/23/21 11:39 AM, Sebastian Huber wrote:
> Add __gcov_info_to_gcda() to libgcov to get the gcda data for a gcda info in a
> freestanding environment. It is intended to be used with the
> -fprofile-info-section option. A crude test program which doesn't use a linker
> script is (use "gcc -coverage -fprofile-info-section -lgcc test.c" to compile
> it):
The patch can be installed once the following nits are fixed:
>
> #include <gcov.h>
> #include <stdio.h>
> #include <stdlib.h>
>
> extern const struct gcov_info *my_info;
>
> static void
> filename (const char *f, void *arg)
> {
> printf("filename: %s\n", f);
> }
>
> static void
> dump (const void *d, unsigned n, void *arg)
> {
> const unsigned char *c = d;
>
> for (unsigned i = 0; i < n; ++i)
> printf ("%02x", c[i]);
> }
>
> static void *
> allocate (unsigned length, void *arg)
> {
> return malloc (length);
> }
>
> int main()
> {
> __asm__ volatile (".set my_info, .LPBX2");
> __gcov_info_to_gcda (my_info, filename, dump, allocate, NULL);
> return 0;
> }
>
> With this patch, <stdint.h> is included in libgcov-driver.c even if
> inhibit_libc is defined. This header file should be also available for
> freestanding environments. If this is not the case, then we have to define
> intptr_t somehow.
>
> The patch removes one use of memset() which makes the <string.h> include
> superfluous.
>
> gcc/
>
> * gcov-io.h (gcov_write): Declare.
> * gcov-io.c (gcov_write): New.
> (gcov_write_counter): Remove.
> (gcov_write_tag_length): Likewise.
> (gcov_write_summary): Replace gcov_write_tag_length() with calls to
> gcov_write_unsigned().
> * doc/invoke.texi (fprofile-info-section): Mention
> __gcov_info_to_gdca().
>
> gcc/testsuite/
>
> * gcc.dg/gcov-info-to-gcda.c: New test.
>
> libgcc/
>
> * Makefile.in (LIBGCOV_DRIVER): Add _gcov_info_to_gcda.
> * gcov.h (gcov_info): Declare.
> (__gcov_info_to_gdca): Likewise.
> * libgcov.h (gcov_write_counter): Remove.
> (gcov_write_tag_length): Likewise.
> * libgcov-driver.c (#include <stdint.h>): New.
> (#include <string.h>): Remove.
> (NEED_L_GCOV): Conditionally define.
> (NEED_L_GCOV_INFO_TO_GCDA): Likewise.
> (are_all_counters_zero): New.
> (gcov_dump_handler): Likewise.
> (gcov_allocate_handler): Likewise.
> (dump_unsigned): Likewise.
> (dump_counter): Likewise.
> (write_topn_counters): Add dump_fn, allocate_fn, and arg parameters.
> Use dump_unsigned() and dump_counter().
> (write_one_data): Add dump_fn, allocate_fn, and arg parameters. Use
> dump_unsigned(), dump_counter(), and are_all_counters_zero().
> (__gcov_info_to_gcda): New.
> ---
> gcc/doc/invoke.texi | 80 +++++++--
> gcc/gcov-io.c | 36 ++---
> gcc/gcov-io.h | 1 +
> gcc/testsuite/gcc.dg/gcov-info-to-gcda.c | 60 +++++++
> libgcc/Makefile.in | 2 +-
> libgcc/gcov.h | 19 +++
> libgcc/libgcov-driver.c | 196 ++++++++++++++++++-----
> libgcc/libgcov.h | 5 -
> 8 files changed, 313 insertions(+), 86 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/gcov-info-to-gcda.c
>
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 32697e6117c0..5f31312b9485 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -14798,17 +14798,17 @@ To optimize the program based on the collected profile information, use
> Register the profile information in the specified section instead of using a
> constructor/destructor. The section name is @var{name} if it is specified,
> otherwise the section name defaults to @code{.gcov_info}. A pointer to the
> -profile information generated by @option{-fprofile-arcs} or
> -@option{-ftest-coverage} 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 systems with limited resources
> -which do not support constructors and destructors. The linker could collect
> -the input sections in a continuous memory block and define start and end
> -symbols. The runtime support could dump the profiling information registered
> -in this linker set during program termination to a serial line for example. A
> -GNU linker script example which defines a linker output section follows:
> +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
> +environments (for example embedded systems) with limited resources which do not
> +support constructors/destructors or the C library file I/O.
> +
> +The linker could collect the input sections in a continuous memory block and
> +define start and end symbols. A GNU linker script example which defines a
> +linker output section follows:
>
> @smallexample
> .gcov_info :
> @@ -14819,6 +14819,64 @@ GNU linker script example which defines a linker output section follows:
> @}
> @end smallexample
>
> +The program could dump the profiling information registered in this linker set
> +for example like this:
> +
> +@smallexample
> +#include <gcov.h>
> +#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);
> +@}
> +
> +static void
> +dump (const void *d, unsigned n, void *arg)
> +@{
> + const unsigned char *c = d;
> +
> + for (unsigned i = 0; i < n; ++i)
> + printf ("%02x", c[i]);
> +@}
> +
> +static void *
> +allocate (unsigned length, void *arg)
> +@{
> + return malloc (length);
> +@}
> +
> +static void
> +dump_gcov_info (void)
> +@{
> + const struct gcov_info **info = __gcov_info_start;
> + const struct gcov_info **end = __gcov_info_end;
> +
> + /* Obfuscate variable to prevent compiler optimizations. */
> + __asm__ ("" : "+r" (end));
> +
> + while (info != end)
> + @{
> + void *arg = NULL;
> + __gcov_info_to_gcda (*info, filename, dump, allocate, arg);
> + putchar ('\n');
> + ++info;
> + @}
> +@}
> +
> +int
> +main()
> +@{
> + dump_gcov_info();
> + return 0;
> +@}
> +@end smallexample
> +
> @item -fprofile-note=@var{path}
> @opindex fprofile-note
>
> diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c
> index 4b1e11d45305..864c01f04a97 100644
> --- a/gcc/gcov-io.c
> +++ b/gcc/gcov-io.c
> @@ -227,30 +227,25 @@ gcov_magic (gcov_unsigned_t magic, gcov_unsigned_t expected)
> #endif
>
> #if !IN_GCOV
> -/* Write unsigned VALUE to coverage file. */
> +/* Write DATA of LENGTH characters to coverage file. */
>
> GCOV_LINKAGE void
> -gcov_write_unsigned (gcov_unsigned_t value)
> +gcov_write (const void *data, unsigned length)
> {
> - gcov_unsigned_t r = fwrite (&value, sizeof (value), 1, gcov_var.file);
> + gcov_unsigned_t r = fwrite (data, length, 1, gcov_var.file);
> if (r != 1)
> gcov_var.error = 1;
> }
>
> -/* Write counter VALUE to coverage file. Sets error flag
> - appropriately. */
> +/* Write unsigned VALUE to coverage file. */
>
> -#if IN_LIBGCOV
> GCOV_LINKAGE void
> -gcov_write_counter (gcov_type value)
> +gcov_write_unsigned (gcov_unsigned_t value)
> {
> - gcov_write_unsigned ((gcov_unsigned_t) value);
> - if (sizeof (value) > sizeof (gcov_unsigned_t))
> - gcov_write_unsigned ((gcov_unsigned_t) (value >> 32));
> - else
> - gcov_write_unsigned (0);
> + gcov_unsigned_t r = fwrite (&value, sizeof (value), 1, gcov_var.file);
> + if (r != 1)
> + gcov_var.error = 1;
> }
> -#endif /* IN_LIBGCOV */
>
> #if !IN_LIBGCOV
> /* Write STRING to coverage file. Sets error flag on file
> @@ -347,22 +342,13 @@ gcov_write_length (gcov_position_t position)
>
> #else /* IN_LIBGCOV */
>
> -/* Write a tag TAG and length LENGTH. */
> -
> -GCOV_LINKAGE void
> -gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length)
> -{
> - gcov_write_unsigned (tag);
> - gcov_write_unsigned (length);
> -}
> -
> -/* Write a summary structure to the gcov file. Return nonzero on
> - overflow. */
> +/* Write a summary structure to the gcov file. */
>
> GCOV_LINKAGE void
> gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary)
> {
> - gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH);
> + gcov_write_unsigned (tag);
> + gcov_write_unsigned (GCOV_TAG_SUMMARY_LENGTH);
> gcov_write_unsigned (summary->runs);
> gcov_write_unsigned (summary->sum_max);
> }
> diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
> index 538bee81263a..99e1964c1094 100644
> --- a/gcc/gcov-io.h
> +++ b/gcc/gcov-io.h
> @@ -367,6 +367,7 @@ char *mangle_path (char const *base);
>
> #if !IN_GCOV
> /* Available outside gcov */
> +GCOV_LINKAGE void gcov_write (const void *, unsigned) ATTRIBUTE_HIDDEN;
> GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t) ATTRIBUTE_HIDDEN;
> #endif
>
> diff --git a/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c b/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c
> new file mode 100644
> index 000000000000..390f377de4fe
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c
> @@ -0,0 +1,60 @@
> +/* { dg-do run } */
> +/* { dg-skip-if "profile-info-section" { powerpc-ibm-aix* } } */
> +/* { dg-options "-fprofile-arcs -fprofile-info-section" } */
> +
> +#define assert(expr) \
> + ((expr) \
> + ? (void)0 \
> + : (__builtin_printf ("%s:%i: Assertion `%s' failed.\n", \
> + __FILE__, __LINE__, #expr), \
> + __builtin_abort ()))
> +
> +struct gcov_info;
> +
> +extern void
> +__gcov_info_to_gcda (const struct gcov_info *__info,
> + void (*__filename_fn) (const char *, void *),
> + void (*__dump_fn) (const void *, unsigned, void *),
> + void *(*__allocate_fn) (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 void
> +dump (const void *d, unsigned n, void *arg)
> +{
> + unsigned *m = (unsigned *)arg;
> + assert (arg == &counter);
> +
> + if (*m == 0)
> + {
> + const unsigned *u = d;
> + assert (*u == 0x67636461);
> + }
> +
> + *m += n;
> +}
> +
> +static void *
> +allocate (unsigned length, void *arg)
> +{
> + assert (arg == &counter);
> + return __builtin_malloc (length);
> +}
> +
> +int main()
> +{
> + __asm__ volatile (".set my_info, .LPBX2");
> + __gcov_info_to_gcda (my_info, filename, dump, allocate, &counter);
> + assert (counter > 4);
> + return 0;
> +}
> diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
> index 2c8be561eb53..7ec975845544 100644
> --- a/libgcc/Makefile.in
> +++ b/libgcc/Makefile.in
> @@ -908,7 +908,7 @@ LIBGCOV_INTERFACE = _gcov_dump _gcov_fork \
> _gcov_execl _gcov_execlp \
> _gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset \
> _gcov_lock_unlock
> -LIBGCOV_DRIVER = _gcov
> +LIBGCOV_DRIVER = _gcov _gcov_info_to_gcda
>
> libgcov-merge-objects = $(patsubst %,%$(objext),$(LIBGCOV_MERGE))
> libgcov-profiler-objects = $(patsubst %,%$(objext),$(LIBGCOV_PROFILER))
> diff --git a/libgcc/gcov.h b/libgcc/gcov.h
> index e6492cdd31ea..66d03bf4e5d4 100644
> --- a/libgcc/gcov.h
> +++ b/libgcc/gcov.h
> @@ -25,6 +25,8 @@
> #ifndef GCC_GCOV_H
> #define GCC_GCOV_H
>
> +struct gcov_info;
> +
> /* Set all counters to zero. */
>
> extern void __gcov_reset (void);
> @@ -33,4 +35,21 @@ extern void __gcov_reset (void);
>
> extern void __gcov_dump (void);
>
> +/* Convert the gcov information referenced by INFO to a gcda data stream.
> + The FILENAME_FN callback is called exactly once with the filename associated
> + with the gcov information. The filename may be NULL. Afterwards, 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 gcda data
> + 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. */
> +
> +extern void
> +__gcov_info_to_gcda (const struct gcov_info *__info,
> + void (*__filename_fn) (const char *, void *),
> + void (*__dump_fn) (const void *, unsigned, void *),
> + void *(*__allocate_fn) (unsigned, void *),
> + void *__arg);
> +
> #endif /* GCC_GCOV_H */
> diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
> index df7ccb235677..32e312ec3cfa 100644
> --- a/libgcc/libgcov-driver.c
> +++ b/libgcc/libgcov-driver.c
> @@ -26,6 +26,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
> #include "libgcov.h"
> #include "gcov-io.h"
>
> +#include <stdint.h>
> +
> +/* Return 1, if all counter values are zero, otherwise 0. */
> +
> +static inline int
> +are_all_counters_zero (const struct gcov_ctr_info *ci_ptr)
> +{
> + for (unsigned i = 0; i < ci_ptr->num; i++)
> + if (ci_ptr->values[i] != 0)
> + return 0;
> +
> + return 1;
> +}
> +
> #if defined(inhibit_libc)
> /* If libc and its header files are not available, provide dummy functions. */
>
> @@ -35,8 +49,6 @@ void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
>
> #else /* inhibit_libc */
>
> -#include <string.h>
> -
> #if GCOV_LOCKED
> #include <fcntl.h>
> #include <errno.h>
> @@ -51,8 +63,17 @@ void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
> #include <sys/mman.h>
> #endif
>
> -#ifdef L_gcov
> +#endif /* inhibit_libc */
> +
> +#if defined(L_gcov) && !defined(inhibit_libc)
> +#define NEED_L_GCOV
> +#endif
>
> +#if defined(L_gcov_info_to_gcda) && !IN_GCOV_TOOL
> +#define NEED_L_GCOV_INFO_TO_GCDA
> +#endif
> +
> +#ifdef NEED_L_GCOV
> /* A utility function for outputting errors. */
> static int gcov_error (const char *, ...);
>
> @@ -343,6 +364,51 @@ read_error:
> return -1;
> }
>
> +/* Write the DATA of LENGTH characters to the gcov file. */
> +
> +static void
> +gcov_dump_handler (const void *data,
> + unsigned length,
> + void *arg ATTRIBUTE_UNUSED)
> +{
> + gcov_write (data, length);
> +}
> +
> +/* Allocate SIZE characters and return the address of the allocated memory. */
> +
> +static void *
> +gcov_allocate_handler (unsigned size, void *arg ATTRIBUTE_UNUSED)
> +{
> + return xmalloc (size);
> +}
> +#endif /* NEED_L_GCOV */
> +
> +#if defined(NEED_L_GCOV) || defined(NEED_L_GCOV_INFO_TO_GCDA)
> +/* Dump the WORD using the DUMP handler called with ARG. */
> +
> +static inline void
> +dump_unsigned (gcov_unsigned_t word,
> + void (*dump_fn) (const void *, unsigned, void *),
> + void *arg)
> +{
> + (*dump_fn) (&word, sizeof (word), arg);
> +}
> +
> +/* Dump the COUNTER using the DUMP handler called with ARG. */
> +
> +static inline void
> +dump_counter (gcov_type counter,
> + void (*dump_fn) (const void *, unsigned, void *),
> + void *arg)
> +{
> + dump_unsigned ((gcov_unsigned_t)counter, dump_fn, arg);
> +
> + if (sizeof (counter) > sizeof (gcov_unsigned_t))
> + dump_unsigned ((gcov_unsigned_t)(counter >> 32), dump_fn, arg);
> + else
> + dump_unsigned (0, dump_fn, arg);
> +}
> +
> #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
>
> /* Store all TOP N counters where each has a dynamic length. */
> @@ -350,7 +416,10 @@ read_error:
> static void
> write_topn_counters (const struct gcov_ctr_info *ci_ptr,
> unsigned t_ix,
> - gcov_unsigned_t n_counts)
> + gcov_unsigned_t n_counts,
> + void (*dump_fn) (const void *, unsigned, void *),
> + void *(*allocate_fn)(unsigned, void *),
> + void *arg)
> {
> unsigned counters = n_counts / GCOV_TOPN_MEM_COUNTERS;
> gcc_assert (n_counts % GCOV_TOPN_MEM_COUNTERS == 0);
> @@ -365,46 +434,49 @@ write_topn_counters (const struct gcov_ctr_info *ci_ptr,
> if (list_sizes == NULL || counters > list_size_length)
> {
> list_size_length = MAX (LIST_SIZE_MIN_LENGTH, 2 * counters);
> -#if HAVE_SYS_MMAN_H
> +#if !defined(inhibit_libc) && HAVE_SYS_MMAN_H
> list_sizes
> = (unsigned *)malloc_mmap (list_size_length * sizeof (unsigned));
> #endif
>
> /* Malloc fallback. */
> if (list_sizes == NULL)
> - list_sizes = (unsigned *)xmalloc (list_size_length * sizeof (unsigned));
> + list_sizes =
> + (unsigned *)(*allocate_fn) (list_size_length * sizeof (unsigned),
> + arg);
> }
>
> - memset (list_sizes, 0, counters * sizeof (unsigned));
> unsigned pair_total = 0;
>
> for (unsigned i = 0; i < counters; i++)
> {
> gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2];
> + unsigned sizes = 0;
> +
> for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start;
> node != NULL; node = node->next)
> - {
> - ++pair_total;
> - ++list_sizes[i];
> - }
> + ++sizes;
> +
> + pair_total += sizes;
> + list_sizes[i] = sizes;
> }
>
> unsigned disk_size = GCOV_TOPN_DISK_COUNTERS * counters + 2 * pair_total;
> - gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
> - GCOV_TAG_COUNTER_LENGTH (disk_size));
> + dump_unsigned (GCOV_TAG_FOR_COUNTER (t_ix), dump_fn, arg),
> + dump_unsigned (GCOV_TAG_COUNTER_LENGTH (disk_size), dump_fn, arg);
>
> for (unsigned i = 0; i < counters; i++)
> {
> - gcov_write_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i]);
> - gcov_write_counter (list_sizes[i]);
> + dump_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i], dump_fn, arg);
> + dump_counter (list_sizes[i], dump_fn, arg);
> gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2];
>
> unsigned j = 0;
> for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start;
> j < list_sizes[i]; node = node->next, j++)
> {
> - gcov_write_counter (node->value);
> - gcov_write_counter (node->count);
> + dump_counter (node->value, dump_fn, arg);
> + dump_counter (node->count, dump_fn, arg);
> }
> }
> }
> @@ -415,25 +487,36 @@ write_topn_counters (const struct gcov_ctr_info *ci_ptr,
>
> static void
> write_one_data (const struct gcov_info *gi_ptr,
> - const struct gcov_summary *prg_p)
> + const struct gcov_summary *prg_p,
> + void (*dump_fn) (const void *, unsigned, void *),
> + void *(*allocate_fn) (unsigned, void *),
> + void *arg)
> {
> unsigned f_ix;
>
> - gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
> - gcov_write_unsigned (gi_ptr->stamp);
> + dump_unsigned (GCOV_DATA_MAGIC, dump_fn, arg);
> + dump_unsigned (GCOV_VERSION, dump_fn, arg);
> + dump_unsigned (gi_ptr->stamp, dump_fn, arg);
>
> +#ifdef NEED_L_GCOV
> /* Generate whole program statistics. */
> gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, prg_p);
> +#else
> + (void)prg_p;
Can you please use rather ATTRIBUTE_UNUSED for the argument?
> +#endif
>
> /* Write execution counts for each function. */
> for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
> {
> +#ifdef NEED_L_GCOV
> unsigned buffered = 0;
> +#endif
> const struct gcov_fn_info *gfi_ptr;
> const struct gcov_ctr_info *ci_ptr;
> gcov_unsigned_t length;
> unsigned t_ix;
>
> +#ifdef NEED_L_GCOV
> if (fn_buffer && fn_buffer->fn_ix == f_ix)
> {
> /* Buffered data from another program. */
> @@ -442,6 +525,7 @@ write_one_data (const struct gcov_info *gi_ptr,
> length = GCOV_TAG_FUNCTION_LENGTH;
> }
> else
> +#endif
> {
> gfi_ptr = gi_ptr->functions[f_ix];
> if (gfi_ptr && gfi_ptr->key == gi_ptr)
> @@ -450,13 +534,14 @@ write_one_data (const struct gcov_info *gi_ptr,
> length = 0;
> }
>
> - gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
> + dump_unsigned (GCOV_TAG_FUNCTION, dump_fn, arg);
> + dump_unsigned (length, dump_fn, arg);
> if (!length)
> continue;
>
> - gcov_write_unsigned (gfi_ptr->ident);
> - gcov_write_unsigned (gfi_ptr->lineno_checksum);
> - gcov_write_unsigned (gfi_ptr->cfg_checksum);
> + dump_unsigned (gfi_ptr->ident, dump_fn, arg);
> + dump_unsigned (gfi_ptr->lineno_checksum, dump_fn, arg);
> + dump_unsigned (gfi_ptr->cfg_checksum, dump_fn, arg);
>
> ci_ptr = gfi_ptr->ctrs;
> for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
> @@ -469,39 +554,43 @@ write_one_data (const struct gcov_info *gi_ptr,
> n_counts = ci_ptr->num;
>
> if (t_ix == GCOV_COUNTER_V_TOPN || t_ix == GCOV_COUNTER_V_INDIR)
> - write_topn_counters (ci_ptr, t_ix, n_counts);
> + write_topn_counters (ci_ptr,
> + t_ix,
> + n_counts,
> + dump_fn,
> + allocate_fn,
> + arg);
Please reduce the number of newlines.
> else
> {
> - /* Do not stream when all counters are zero. */
> - int all_zeros = 1;
> - for (unsigned i = 0; i < n_counts; i++)
> - if (ci_ptr->values[i] != 0)
> - {
> - all_zeros = 0;
> - break;
> - }
> -
> - if (all_zeros)
> - gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
> - GCOV_TAG_COUNTER_LENGTH (-n_counts));
> + dump_unsigned (GCOV_TAG_FOR_COUNTER (t_ix), dump_fn, arg);
> + if (are_all_counters_zero (ci_ptr))
> + /* Do not stream when all counters are zero. */
> + dump_unsigned (GCOV_TAG_COUNTER_LENGTH (-n_counts),
> + dump_fn,
> + arg);
Likewise here.
> else
> {
> - gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
> - GCOV_TAG_COUNTER_LENGTH (n_counts));
> + dump_unsigned (GCOV_TAG_COUNTER_LENGTH (n_counts),
> + dump_fn,
> + arg);
> for (unsigned i = 0; i < n_counts; i++)
> - gcov_write_counter (ci_ptr->values[i]);
> + dump_counter (ci_ptr->values[i], dump_fn, arg);
> }
> }
>
> ci_ptr++;
> }
> +#ifdef NEED_L_GCOV
> if (buffered)
> fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
> +#endif
> }
>
> - gcov_write_unsigned (0);
> + dump_unsigned (0, dump_fn, arg);
> }
> +#endif /* NEED_L_GCOV || NEED_L_GCOV_INFO_TO_GCDA */
>
> +#ifdef NEED_L_GCOV
> /* Dump the coverage counts for one gcov_info object. 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
> @@ -550,7 +639,11 @@ dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
> summary = gi_ptr->summary;
> #endif
>
> - write_one_data (gi_ptr, &summary);
> + write_one_data (gi_ptr,
> + &summary,
> + gcov_dump_handler,
> + gcov_allocate_handler,
> + NULL);
Same here.
Martin
> /* fall through */
>
> read_fatal:;
> @@ -680,5 +773,20 @@ __gcov_init (struct gcov_info *info)
> }
> }
> #endif /* !IN_GCOV_TOOL */
> -#endif /* L_gcov */
> -#endif /* inhibit_libc */
> +#endif /* NEED_L_GCOV */
> +
> +#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. */
> +
> +void
> +__gcov_info_to_gcda (const struct gcov_info *gi_ptr,
> + void (*filename_fn) (const char *, void *),
> + void (*dump_fn) (const void *, unsigned, void *),
> + void *(*allocate_fn) (unsigned, void *),
> + void *arg)
> +{
> + (*filename_fn) (gi_ptr->filename, arg);
> + write_one_data (gi_ptr, NULL, dump_fn, allocate_fn, arg);
> +}
> +#endif /* NEED_L_GCOV_INFO_TO_GCDA */
> diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
> index 8d323db05386..9c537253293f 100644
> --- a/libgcc/libgcov.h
> +++ b/libgcc/libgcov.h
> @@ -114,13 +114,11 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
> #define gcov_var __gcov_var
> #define gcov_open __gcov_open
> #define gcov_close __gcov_close
> -#define gcov_write_tag_length __gcov_write_tag_length
> #define gcov_position __gcov_position
> #define gcov_seek __gcov_seek
> #define gcov_rewrite __gcov_rewrite
> #define gcov_is_error __gcov_is_error
> #define gcov_write_unsigned __gcov_write_unsigned
> -#define gcov_write_counter __gcov_write_counter
> #define gcov_write_summary __gcov_write_summary
> #define gcov_read_unsigned __gcov_read_unsigned
> #define gcov_read_counter __gcov_read_counter
> @@ -345,9 +343,6 @@ extern int __gcov_execve (const char *, char *const [], char *const [])
>
> /* Functions that only available in libgcov. */
> GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
> -GCOV_LINKAGE void gcov_write_counter (gcov_type) ATTRIBUTE_HIDDEN;
> -GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t)
> - ATTRIBUTE_HIDDEN;
> GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
> const struct gcov_summary *)
> ATTRIBUTE_HIDDEN;
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] gcov: Add __gcov_info_to_gdca()
2021-08-05 12:53 ` Martin Liška
@ 2021-08-06 5:31 ` Sebastian Huber
2021-08-06 7:50 ` Christophe Lyon
0 siblings, 1 reply; 8+ messages in thread
From: Sebastian Huber @ 2021-08-06 5:31 UTC (permalink / raw)
To: Martin Liška, gcc-patches
On 05/08/2021 14:53, Martin Liška wrote:
> On 7/23/21 11:39 AM, Sebastian Huber wrote:
>> Add __gcov_info_to_gcda() to libgcov to get the gcda data for a gcda
>> info in a
>> freestanding environment. It is intended to be used with the
>> -fprofile-info-section option. A crude test program which doesn't use
>> a linker
>> script is (use "gcc -coverage -fprofile-info-section -lgcc test.c" to
>> compile
>> it):
>
> The patch can be installed once the following nits are fixed:
Thanks for the review, I checked it in like this:
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=9124bbe1857f0d3a3015d6461d5f8d04f07cab85
I hope the format is now all right.
--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax: +49-89-18 94 741 - 08
Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] gcov: Add __gcov_info_to_gdca()
2021-08-06 5:31 ` Sebastian Huber
@ 2021-08-06 7:50 ` Christophe Lyon
2021-08-06 8:05 ` Sebastian Huber
0 siblings, 1 reply; 8+ messages in thread
From: Christophe Lyon @ 2021-08-06 7:50 UTC (permalink / raw)
To: Sebastian Huber; +Cc: Martin Liška, GCC Patches
On Fri, Aug 6, 2021 at 7:31 AM Sebastian Huber <
sebastian.huber@embedded-brains.de> wrote:
> On 05/08/2021 14:53, Martin Liška wrote:
> > On 7/23/21 11:39 AM, Sebastian Huber wrote:
> >> Add __gcov_info_to_gcda() to libgcov to get the gcda data for a gcda
> >> info in a
> >> freestanding environment. It is intended to be used with the
> >> -fprofile-info-section option. A crude test program which doesn't use
> >> a linker
> >> script is (use "gcc -coverage -fprofile-info-section -lgcc test.c" to
> >> compile
> >> it):
> >
> > The patch can be installed once the following nits are fixed:
>
> Thanks for the review, I checked it in like this:
>
>
> https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=9124bbe1857f0d3a3015d6461d5f8d04f07cab85
>
> I hope the format is now all right.
>
>
Hi,
Looks like there's a problem with your patch:
/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/./gcc/xgcc
-B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/./gcc/
-B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/bin/
-B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/lib/
-isystem
/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/include
-isystem
/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/sys-include
-g -O2 -O2 -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -W -Wall
-Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes
-Wmissing-prototypes -Wold-style-definition -isystem ./include
-fno-inline -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector
-Dinhibit_libc -fno-inline -I. -I. -I../.././gcc
-I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc
-I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/.
-I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/../gcc
-I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/../include
-o _gcov.o -MT _gcov.o -MD -MP -MF _gcov.dep -DL_gcov -c
/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/libgcov-driver.c
In file included from
/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/libgcov-driver.c:29:
/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/gcc/include/stdint.h:9:16:
fatal error: stdint.h: No such file or directory
9 | # include_next <stdint.h>
| ^~~~~~~~~~
compilation terminated.
make[2]: *** [Makefile:928: _gcov.o] Error 1
make[2]: *** Waiting for unfinished jobs....
Can you check?
Thanks,
Christophe
--
> embedded brains GmbH
> Herr Sebastian HUBER
> Dornierstr. 4
> 82178 Puchheim
> Germany
> email: sebastian.huber@embedded-brains.de
> phone: +49-89-18 94 741 - 16
> fax: +49-89-18 94 741 - 08
>
> Registergericht: Amtsgericht München
> Registernummer: HRB 157899
> Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
> Unsere Datenschutzerklärung finden Sie hier:
> https://embedded-brains.de/datenschutzerklaerung/
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] gcov: Add __gcov_info_to_gdca()
2021-08-06 7:50 ` Christophe Lyon
@ 2021-08-06 8:05 ` Sebastian Huber
2021-08-06 9:15 ` Christophe Lyon
2021-08-06 10:26 ` Martin Liška
0 siblings, 2 replies; 8+ messages in thread
From: Sebastian Huber @ 2021-08-06 8:05 UTC (permalink / raw)
To: Christophe Lyon; +Cc: Martin Liška, GCC Patches
[-- Attachment #1: Type: text/plain, Size: 2728 bytes --]
Hello Christophe,
On 06/08/2021 09:50, Christophe Lyon wrote:
> Looks like there's a problem with your patch:
> /tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/./gcc/xgcc -B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/./gcc/ -B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/bin/ -B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/lib/ -isystem /tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/include -isystem /tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/sys-include -g -O2 -O2 -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -fno-inline -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc -fno-inline -I. -I. -I../.././gcc -I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc -I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/. -I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/../gcc -I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/../include -o _gcov.o -MT _gcov.o -MD -MP -MF _gcov.dep -DL_gcov -c /tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/libgcov-driver.c
>
> In file included from
> /tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/libgcov-driver.c:29:
> /tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/gcc/include/stdint.h:9:16:
> fatal error: stdint.h: No such file or directory
> 9 | # include_next <stdint.h>
> | ^~~~~~~~~~
> compilation terminated.
> make[2]: *** [Makefile:928: _gcov.o] Error 1
> make[2]: *** Waiting for unfinished jobs....
>
> Can you check?
I already feared that the <stdint.h> include may cause problems, from
the commit message:
"With this patch, <stdint.h> is included in libgcov-driver.c even if
inhibit_libc is defined. This header file should be also available for
freestanding environments. If this is not the case, then we have to
define intptr_t somehow."
What about the attached patch?
--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax: +49-89-18 94 741 - 08
Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/
[-- Attachment #2: 0001-gcov-Remove-stdint.h-from-libgcov-driver.c.patch --]
[-- Type: text/x-patch, Size: 1963 bytes --]
From 9e91c623116313312408a8809f32eac1f7ef6b16 Mon Sep 17 00:00:00 2001
From: Sebastian Huber <sebastian.huber@embedded-brains.de>
Date: Fri, 6 Aug 2021 09:57:43 +0200
Subject: [PATCH] gcov: Remove <stdint.h> from libgcov-driver.c
In the patch to add __gcov_info_to_gcda(), the include of <stdint.h> was added
to libgcov-driver.c even if inhibit_libc is defined. It turned out that this
header file is not always available. Remove the include of <stdin.h> and
replace the intptr_t with the compiler provided __INTPTR_TYPE__.
libgcc/
* libgcov-driver.c (#include <stdint.h>): Remove.
(write_topn_counters): Use __INTPTR_TYPE__ instead of intptr_t.
---
libgcc/libgcov-driver.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 9d7bc9c79950..087f71e01077 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -26,8 +26,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "libgcov.h"
#include "gcov-io.h"
-#include <stdint.h>
-
/* Return 1, if all counter values are zero, otherwise 0. */
static inline int
@@ -453,7 +451,7 @@ write_topn_counters (const struct gcov_ctr_info *ci_ptr,
gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2];
unsigned sizes = 0;
- for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start;
+ for (struct gcov_kvp *node = (struct gcov_kvp *)(__INTPTR_TYPE__)start;
node != NULL; node = node->next)
++sizes;
@@ -472,7 +470,7 @@ write_topn_counters (const struct gcov_ctr_info *ci_ptr,
gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2];
unsigned j = 0;
- for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start;
+ for (struct gcov_kvp *node = (struct gcov_kvp *)(__INTPTR_TYPE__)start;
j < list_sizes[i]; node = node->next, j++)
{
dump_counter (node->value, dump_fn, arg);
--
2.26.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] gcov: Add __gcov_info_to_gdca()
2021-08-06 8:05 ` Sebastian Huber
@ 2021-08-06 9:15 ` Christophe Lyon
2021-08-06 10:26 ` Martin Liška
1 sibling, 0 replies; 8+ messages in thread
From: Christophe Lyon @ 2021-08-06 9:15 UTC (permalink / raw)
To: Sebastian Huber; +Cc: Martin Liška, GCC Patches
On Fri, Aug 6, 2021 at 10:05 AM Sebastian Huber <
sebastian.huber@embedded-brains.de> wrote:
> Hello Christophe,
>
> On 06/08/2021 09:50, Christophe Lyon wrote:
> > Looks like there's a problem with your patch:
> >
> /tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/./gcc/xgcc
> -B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/./gcc/
> -B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/bin/
> -B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/lib/
> -isystem
> /tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/include
> -isystem
> /tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/sys-include
> -g -O2 -O2 -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -W -Wall
> -Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes
> -Wmissing-prototypes -Wold-style-definition -isystem ./include -fno-inline
> -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc
> -fno-inline -I. -I. -I../.././gcc
> -I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc
> -I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/.
> -I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/../gcc
> -I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/../include
> -o _gcov.o -MT _gcov.o -MD -MP -MF _gcov.dep -DL_gcov -c
> /tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/libgcov-driver.c
> >
> > In file included from
> >
> /tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/libgcov-driver.c:29:
> >
> /tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/gcc/include/stdint.h:9:16:
>
> > fatal error: stdint.h: No such file or directory
> > 9 | # include_next <stdint.h>
> > | ^~~~~~~~~~
> > compilation terminated.
> > make[2]: *** [Makefile:928: _gcov.o] Error 1
> > make[2]: *** Waiting for unfinished jobs....
> >
> > Can you check?
>
> I already feared that the <stdint.h> include may cause problems, from
> the commit message:
>
> "With this patch, <stdint.h> is included in libgcov-driver.c even if
> inhibit_libc is defined. This header file should be also available for
> freestanding environments. If this is not the case, then we have to
> define intptr_t somehow."
>
> What about the attached patch?
>
Thanks, it does fix the build issue for me.
Christophe
>
> --
> embedded brains GmbH
> Herr Sebastian HUBER
> Dornierstr. 4
> 82178 Puchheim
> Germany
> email: sebastian.huber@embedded-brains.de
> phone: +49-89-18 94 741 - 16
> fax: +49-89-18 94 741 - 08
>
> Registergericht: Amtsgericht München
> Registernummer: HRB 157899
> Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
> Unsere Datenschutzerklärung finden Sie hier:
> https://embedded-brains.de/datenschutzerklaerung/
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] gcov: Add __gcov_info_to_gdca()
2021-08-06 8:05 ` Sebastian Huber
2021-08-06 9:15 ` Christophe Lyon
@ 2021-08-06 10:26 ` Martin Liška
2021-08-06 10:29 ` Sebastian Huber
1 sibling, 1 reply; 8+ messages in thread
From: Martin Liška @ 2021-08-06 10:26 UTC (permalink / raw)
To: Sebastian Huber, Christophe Lyon; +Cc: GCC Patches
On 8/6/21 10:05 AM, Sebastian Huber wrote:
> What about the attached patch?
The patch is fine, please install it.
Martin
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] gcov: Add __gcov_info_to_gdca()
2021-08-06 10:26 ` Martin Liška
@ 2021-08-06 10:29 ` Sebastian Huber
0 siblings, 0 replies; 8+ messages in thread
From: Sebastian Huber @ 2021-08-06 10:29 UTC (permalink / raw)
To: Martin Liška, Christophe Lyon; +Cc: GCC Patches
On 06/08/2021 12:26, Martin Liška wrote:
> On 8/6/21 10:05 AM, Sebastian Huber wrote:
>> What about the attached patch?
>
> The patch is fine, please install it.
Thanks, I checked it in.
--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax: +49-89-18 94 741 - 08
Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-08-06 10:29 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-23 9:39 [PATCH v3] gcov: Add __gcov_info_to_gdca() Sebastian Huber
2021-08-05 12:53 ` Martin Liška
2021-08-06 5:31 ` Sebastian Huber
2021-08-06 7:50 ` Christophe Lyon
2021-08-06 8:05 ` Sebastian Huber
2021-08-06 9:15 ` Christophe Lyon
2021-08-06 10:26 ` Martin Liška
2021-08-06 10:29 ` Sebastian Huber
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).