public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool
@ 2022-03-31 11:35 Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 01/12] gcov-tool: Allow merging of empty profile lists Sebastian Huber
                   ` (12 more replies)
  0 siblings, 13 replies; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

This patch set is a proof of concept.

The aim is to better support gcov in free-standing environments. For example,
you can run a test executable which dumps all gcov info objects in a serial
data stream using __gcov_info_to_gcda() and the new __gcov_filename_to_gcfn().
It could be encoded as base64. It could be also compressed. On the host you
unpack the encoded data stream and feed it into gcov-tool using the new
"merge-stream" subcommand:

gcov-tool --help
Usage: gcov-tool [OPTION]... SUB_COMMAND [OPTION]...

Offline tool to handle gcda counts

  -h, --help                            Print this help, then exit
  -v, --version                         Print version number, then exit
  merge-stream [options] [stream-file]  Merge coverage stream file (or stdin)
                                        and coverage file contents
    -v, --verbose                       Verbose mode
    -w, --weight <w1,w2>                Set weights (float point values)

Example:

base64 -d log.txt | gcov-tool merge-stream

The patch set does not change the format of gcda files.

TODO:

* Documentation
* Tests

Sebastian Huber (12):
  gcov-tool: Allow merging of empty profile lists
  gcov: Add mode to all gcov_open()
  gcov: Add open mode parameter to gcov_do_dump()
  gcov: Make gcov_seek() static
  gcov: Add __gcov_filename_to_gcfn()
  gcov-tool: Support file input from stdin
  gcov: Use xstrdup()
  gcov: Move prepend to list to read_gcda_file()
  gcov: Move gcov_open() to caller of read_gcda_file()
  gcov: Fix integer types in ftw_read_file()
  gcov: Record EOF error during read
  gcov-tool: Add merge-stream subcommand

 gcc/gcov-io.cc                 |  76 ++++++++++++++-----
 gcc/gcov-io.h                  |  35 +++++----
 gcc/gcov-tool.cc               | 107 +++++++++++++++++++++-----
 libgcc/gcov.h                  |  17 ++++-
 libgcc/libgcov-driver-system.c |   7 +-
 libgcc/libgcov-driver.c        |  42 ++++++++--
 libgcc/libgcov-util.c          | 135 +++++++++++++++++++++++++--------
 libgcc/libgcov.h               |   3 -
 8 files changed, 326 insertions(+), 96 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 01/12] gcov-tool: Allow merging of empty profile lists
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 02/12] gcov: Add mode to all gcov_open() Sebastian Huber
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

The gcov_profile_merge() already had code to deal with profile information
which had no counterpart to merge with.  For profile information from files
with no associated counterpart, the profile information is simply used as is
with the weighting transformation applied.  Make sure that gcov_profile_merge()
works with an empty target profile list.  Return the merged profile list.

gcc/
	* gcov-tool.cc (gcov_profile_merge): Adjust return type.
	(profile_merge): Allow merging of directories which contain no profile
	files.

libgcc/
	* libgcov-util.c (gcov_profile_merge): Return the list of merged
	profiles.  Accept empty target and source profile lists.
---
 gcc/gcov-tool.cc      | 27 ++++++++++-----------------
 libgcc/libgcov-util.c | 19 +++++++++++--------
 2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index f4e42ae763c..2e4083a664d 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -40,7 +40,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #endif
 #include <getopt.h>
 
-extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
+					     struct gcov_info*, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -141,26 +142,18 @@ profile_merge (const char *d1, const char *d2, const char *out, int w1, int w2)
 {
   struct gcov_info *d1_profile;
   struct gcov_info *d2_profile;
-  int ret;
+  struct gcov_info *merged_profile;
 
   d1_profile = gcov_read_profile_dir (d1, 0);
-  if (!d1_profile)
-    return 1;
-
-  if (d2)
-    {
-      d2_profile = gcov_read_profile_dir (d2, 0);
-      if (!d2_profile)
-        return 1;
+  d2_profile = gcov_read_profile_dir (d2, 0);
 
-      /* The actual merge: we overwrite to d1_profile.  */
-      ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
+  /* The actual merge: we overwrite to d1_profile.  */
+  merged_profile = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
 
-      if (ret)
-        return ret;
-    }
-
-  gcov_output_files (out, d1_profile);
+  if (merged_profile)
+    gcov_output_files (out, merged_profile);
+  else if (verbose)
+    fnotice (stdout, "no profile files were merged\n");
 
   return 0;
 }
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ba7fb924b53..100f1b19f1a 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -674,16 +674,16 @@ find_match_gcov_info (struct gcov_info **array, int size,
 }
 
 /* Merge the list of gcov_info objects from SRC_PROFILE to TGT_PROFILE.
-   Return 0 on success: without mismatch.
-   Reutrn 1 on error.  */
+   Return the list of merged gcov_info objects.  Return NULL if the list is
+   empty.  */
 
-int
+struct gcov_info *
 gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info *src_profile,
                     int w1, int w2)
 {
   struct gcov_info *gi_ptr;
   struct gcov_info **tgt_infos;
-  struct gcov_info *tgt_tail;
+  struct gcov_info **tgt_tail;
   struct gcov_info **in_src_not_tgt;
   unsigned tgt_cnt = 0, src_cnt = 0;
   unsigned unmatch_info_cnt = 0;
@@ -703,7 +703,10 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info *src_profile
   for (gi_ptr = tgt_profile, i = 0; gi_ptr; gi_ptr = gi_ptr->next, i++)
     tgt_infos[i] = gi_ptr;
 
-  tgt_tail = tgt_infos[tgt_cnt - 1];
+  if (tgt_cnt)
+     tgt_tail = &tgt_infos[tgt_cnt - 1]->next;
+  else
+     tgt_tail = &tgt_profile;
 
   /* First pass on tgt_profile, we multiply w1 to all counters.  */
   if (w1 > 1)
@@ -732,14 +735,14 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info *src_profile
       gi_ptr = in_src_not_tgt[i];
       gcov_merge (gi_ptr, gi_ptr, w2 - 1);
       gi_ptr->next = NULL;
-      tgt_tail->next = gi_ptr;
-      tgt_tail = gi_ptr;
+      *tgt_tail = gi_ptr;
+      tgt_tail = &gi_ptr->next;
     }
 
   free (in_src_not_tgt);
   free (tgt_infos);
 
-  return 0;
+  return tgt_profile;
 }
 
 typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*);
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 02/12] gcov: Add mode to all gcov_open()
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 01/12] gcov-tool: Allow merging of empty profile lists Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 03/12] gcov: Add open mode parameter to gcov_do_dump() Sebastian Huber
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

gcc/

	* gcov-io.cc (gcov_open): Always use the mode parameter.
	* gcov-io.h (gcov_open): Declare it unconditionally.

libgcc/

	* libgcov-driver-system.c (gcov_exit_open_gcda_file): Open file for
	reading and writing.
	* libgcov-util.c (read_gcda_file): Open file for reading.
	* libgcov.h (gcov_open): Delete declaration.
---
 gcc/gcov-io.cc                 | 7 -------
 gcc/gcov-io.h                  | 5 +----
 libgcc/libgcov-driver-system.c | 4 ++--
 libgcc/libgcov-util.c          | 2 +-
 libgcc/libgcov.h               | 1 -
 5 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 72c40f8eaa0..017a6e32a5d 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -89,15 +89,8 @@ from_file (gcov_unsigned_t value)
    Return zero on failure, non-zero on success.  */
 
 GCOV_LINKAGE int
-#if IN_LIBGCOV
-gcov_open (const char *name)
-#else
 gcov_open (const char *name, int mode)
-#endif
 {
-#if IN_LIBGCOV
-  int mode = 0;
-#endif
 #if GCOV_LOCKED
   struct flock s_flock;
   int fd;
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 99ce7dbccc8..afe74b002f1 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -347,15 +347,12 @@ struct gcov_summary
    functions for writing.  Your file may become corrupted if you break
    these invariants.  */
 
-#if !IN_LIBGCOV
-GCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/);
-#endif
-
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
 GCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t);
 #endif
 
 /* Available everywhere.  */
+GCOV_LINKAGE int gcov_open (const char *, int) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN;
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index eef6e3cbda1..9abb2fe7f74 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -309,7 +309,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
 
   gf->filename = replace_filename_variables (gf->filename);
 
-  if (!gcov_open (gf->filename))
+  if (!gcov_open (gf->filename, 0))
     {
       /* Open failed likely due to missed directory.
          Create directory and retry to open file. */
@@ -318,7 +318,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
           fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
           return -1;
         }
-      if (!gcov_open (gf->filename))
+      if (!gcov_open (gf->filename, 0))
         {
           fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
           return -1;
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 100f1b19f1a..db157220c9d 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -268,7 +268,7 @@ read_gcda_file (const char *filename)
     k_ctrs_mask[i] = 0;
   k_ctrs_types = 0;
 
-  if (!gcov_open (filename))
+  if (!gcov_open (filename, 1))
     {
       fnotice (stderr, "%s:cannot open\n", filename);
       return NULL;
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 40e845ce3ea..f190547e819 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -343,7 +343,6 @@ extern int __gcov_execve (const char *, char  *const [], char *const [])
   ATTRIBUTE_HIDDEN;
 
 /* Functions that only available in libgcov.  */
-GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
                                       const struct gcov_summary *)
     ATTRIBUTE_HIDDEN;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 03/12] gcov: Add open mode parameter to gcov_do_dump()
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 01/12] gcov-tool: Allow merging of empty profile lists Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 02/12] gcov: Add mode to all gcov_open() Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 04/12] gcov: Make gcov_seek() static Sebastian Huber
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

gcc/

	* gcov-tool.cc (gcov_do_dump): Add mode parameter.
	(gcov_output_files): Open files for reading and writing.

libgcc/

	* libgcov-driver-system.c (gcov_exit_open_gcda_file): Add mode
	parameter.  Pass mode to gcov_open() calls.
	* libgcov-driver.c (dump_one_gcov):  Add mode parameter.  Pass mode to
	gcov_exit_open_gcda_file() call.
	(gcov_do_dump): Add mode parameter.  Pass mode to dump_one_gcov()
	calls.
	(__gcov_dump_one):  Open file for reading and writing.
---
 gcc/gcov-tool.cc               |  4 ++--
 libgcc/libgcov-driver-system.c |  7 ++++---
 libgcc/libgcov-driver.c        | 12 ++++++------
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index 2e4083a664d..d712715cf7e 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -46,7 +46,7 @@ extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
 extern struct gcov_info* gcov_read_profile_dir (const char*, int);
-extern void gcov_do_dump (struct gcov_info *, int);
+extern void gcov_do_dump (struct gcov_info *, int, int);
 extern const char *gcov_get_filename (struct gcov_info *list);
 extern void gcov_set_verbose (void);
 
@@ -124,7 +124,7 @@ gcov_output_files (const char *out, struct gcov_info *profile)
     fatal_error (input_location, "output file %s already exists in folder %s",
 		 filename, out);
 
-  gcov_do_dump (profile, 0);
+  gcov_do_dump (profile, 0, 0);
 
   ret = chdir (pwd);
   if (ret)
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index 9abb2fe7f74..ac405c38e3a 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -261,7 +261,8 @@ allocate_filename_struct (struct gcov_filename *gf)
 
 static int
 gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
-			  struct gcov_filename *gf)
+			  struct gcov_filename *gf,
+			  int mode)
 {
   int append_slash = 0;
   const char *fname = gi_ptr->filename;
@@ -309,7 +310,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
 
   gf->filename = replace_filename_variables (gf->filename);
 
-  if (!gcov_open (gf->filename, 0))
+  if (!gcov_open (gf->filename, mode))
     {
       /* Open failed likely due to missed directory.
          Create directory and retry to open file. */
@@ -318,7 +319,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
           fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
           return -1;
         }
-      if (!gcov_open (gf->filename, 0))
+      if (!gcov_open (gf->filename, mode))
         {
           fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
           return -1;
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 7e52c5676e5..10831e84b61 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -595,14 +595,14 @@ write_one_data (const struct gcov_info *gi_ptr,
 static void
 dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
 	       unsigned run_counted ATTRIBUTE_UNUSED,
-	       gcov_type run_max ATTRIBUTE_UNUSED)
+	       gcov_type run_max ATTRIBUTE_UNUSED, int mode)
 {
   struct gcov_summary summary = {};
   int error;
   gcov_unsigned_t tag;
   fn_buffer = 0;
 
-  error = gcov_exit_open_gcda_file (gi_ptr, gf);
+  error = gcov_exit_open_gcda_file (gi_ptr, gf, mode);
   if (error == -1)
     return;
 
@@ -649,13 +649,13 @@ read_fatal:;
 
 /* Dump all the coverage counts for the program. It first computes program
    summary and then traverses gcov_list list and dumps the gcov_info
-   objects one by one.  */
+   objects one by one.  Use MODE to open files.  */
 
 #if !IN_GCOV_TOOL
 static
 #endif
 void
-gcov_do_dump (struct gcov_info *list, int run_counted)
+gcov_do_dump (struct gcov_info *list, int run_counted, int mode)
 {
   struct gcov_info *gi_ptr;
   struct gcov_filename gf;
@@ -678,7 +678,7 @@ gcov_do_dump (struct gcov_info *list, int run_counted)
   /* Now merge each file.  */
   for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
     {
-      dump_one_gcov (gi_ptr, &gf, run_counted, run_max);
+      dump_one_gcov (gi_ptr, &gf, run_counted, run_max, mode);
       free (gf.filename);
     }
 
@@ -701,7 +701,7 @@ __gcov_dump_one (struct gcov_root *root)
   if (root->dumped)
     return;
 
-  gcov_do_dump (root->list, root->run_counted);
+  gcov_do_dump (root->list, root->run_counted, 0);
   
   root->dumped = 1;
   root->run_counted = 1;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 04/12] gcov: Make gcov_seek() static
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
                   ` (2 preceding siblings ...)
  2022-03-31 11:35 ` [RFC/gcov 03/12] gcov: Add open mode parameter to gcov_do_dump() Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 05/12] gcov: Add __gcov_filename_to_gcfn() Sebastian Huber
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

This function is only used by gcov_write_length() in the gcov-io.cc file.

gcc/

	* gcov-io.cc (gcov_seek): Make it static.
	* gcov-io.h (struct gcov_summary): Do not mention gcov_seek().

libgcc/

	* libgcov.h (gcov_seek): Remove define and declaration.
---
 gcc/gcov-io.cc   | 4 +---
 gcc/gcov-io.h    | 6 +++---
 libgcc/libgcov.h | 2 --
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 017a6e32a5d..fee3130f94a 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -294,17 +294,15 @@ gcov_write_filename (const char *filename)
 
   gcov_write_string (filename);
 }
-#endif
 
 /* Move to a given position in a gcov file.  */
 
-GCOV_LINKAGE void
+static void
 gcov_seek (gcov_position_t base)
 {
   fseek (gcov_var.file, base, SEEK_SET);
 }
 
-#if !IN_LIBGCOV
 /* Write a tag TAG and reserve space for the record length. Return a
    value to be used for gcov_write_length.  */
 
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index afe74b002f1..204ae0ccf7f 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -340,9 +340,9 @@ struct gcov_summary
 /* Functions for reading and writing gcov files. In libgcov you can
    open the file for reading then writing. Elsewhere you can open the
    file either for reading or for writing. When reading a file you may
-   use the gcov_read_* functions, gcov_sync, gcov_position, &
-   gcov_error. When writing a file you may use the gcov_write
-   functions, gcov_seek & gcov_error. When a file is to be rewritten
+   use the gcov_read_* functions, gcov_sync, gcov_position, and
+   gcov_error. When writing a file you may use the gcov_write*
+   functions and gcov_error. When a file is to be rewritten
    you use the functions for reading, then gcov_rewrite then the
    functions for writing.  Your file may become corrupted if you break
    these invariants.  */
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index f190547e819..487bd1464cd 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -115,7 +115,6 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
 #define gcov_open __gcov_open
 #define gcov_close __gcov_close
 #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
@@ -346,7 +345,6 @@ extern int __gcov_execve (const char *, char  *const [], char *const [])
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
                                       const struct gcov_summary *)
     ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_rewrite (void) ATTRIBUTE_HIDDEN;
 
 /* "Counts" stored in gcda files can be a real counter value, or
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 05/12] gcov: Add __gcov_filename_to_gcfn()
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
                   ` (3 preceding siblings ...)
  2022-03-31 11:35 ` [RFC/gcov 04/12] gcov: Make gcov_seek() static Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 06/12] gcov-tool: Support file input from stdin Sebastian Huber
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

gcc/

	* gcov-io.h (GCOV_FILENAME_MAGIC): Define and document.

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.
---
 gcc/gcov-io.h           | 24 ++++++++++++++++--------
 libgcc/gcov.h           | 17 ++++++++++++++++-
 libgcc/libgcov-driver.c | 30 ++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 204ae0ccf7f..30947634d73 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -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"
 
diff --git a/libgcc/gcov.h b/libgcc/gcov.h
index cea93023920..cdd4206f625 100644
--- a/libgcc/gcov.h
+++ b/libgcc/gcov.h
@@ -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 */
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 10831e84b61..a44054a3cb3 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -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.  */
@@ -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
+   free-standing 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 */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 06/12] gcov-tool: Support file input from stdin
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
                   ` (4 preceding siblings ...)
  2022-03-31 11:35 ` [RFC/gcov 05/12] gcov: Add __gcov_filename_to_gcfn() Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-04-07  8:32   ` Martin Liška
  2022-03-31 11:35 ` [RFC/gcov 07/12] gcov: Use xstrdup() Sebastian Huber
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

gcc/

	* gcov-io.cc (GCOV_MODE_STDIN): Define.
	(gcov_position): For gcov-tool, return calculated position if file is
	stdin.
	(gcov_open):  For gcov-tool, use stdin if filename is NULL.
	(gcov_close): For gcov-tool, do not close stdin.
	(gcov_read_bytes): For gcov-tool, update position if file is stdin.
	(gcov_sync): For gcov-tool, discard input if file is stdin.
---
 gcc/gcov-io.cc | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index fee3130f94a..177f81166a6 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -35,8 +35,13 @@ struct gcov_var
   int error;			/* < 0 overflow, > 0 disk error.  */
   int mode;			/* < 0 writing, > 0 reading.  */
   int endian;			/* Swap endianness.  */
+#ifdef IN_GCOV_TOOL
+  gcov_position_t pos;		/* File position for stdin support. */
+#endif
 } gcov_var;
 
+#define GCOV_MODE_STDIN 2
+
 /* Save the current position in the gcov file.  */
 /* We need to expose this function when compiling for gcov-tool.  */
 #ifndef IN_GCOV_TOOL
@@ -45,6 +50,10 @@ static inline
 gcov_position_t
 gcov_position (void)
 {
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.mode == GCOV_MODE_STDIN)
+    return gcov_var.pos;
+#endif
   return ftell (gcov_var.file);
 }
 
@@ -108,6 +117,16 @@ gcov_open (const char *name, int mode)
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
   gcov_var.endian = 0;
 #endif
+#ifdef IN_GCOV_TOOL
+  gcov_var.pos = 0;
+  if (!name)
+    {
+      gcov_nonruntime_assert (gcov_var.mode > 0);
+      gcov_var.file = stdin;
+      gcov_var.mode = GCOV_MODE_STDIN;
+      return 1;
+    }
+#endif
 #if GCOV_LOCKED
   if (mode > 0)
     {
@@ -190,6 +209,11 @@ gcov_open (const char *name, int mode)
 GCOV_LINKAGE int
 gcov_close (void)
 {
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.file == stdin)
+    gcov_var.file = 0;
+  else
+#endif
   if (gcov_var.file)
     {
       if (fclose (gcov_var.file))
@@ -363,6 +387,9 @@ gcov_read_bytes (void *buffer, unsigned count)
   if (read != 1)
     return NULL;
 
+#ifdef IN_GCOV_TOOL
+  gcov_var.pos += count;
+#endif
   return buffer;
 }
 
@@ -499,6 +526,17 @@ gcov_sync (gcov_position_t base, gcov_unsigned_t length)
 {
   gcov_nonruntime_assert (gcov_var.mode > 0);
   base += length;
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.mode == GCOV_MODE_STDIN)
+    {
+      while (gcov_var.pos < base)
+	{
+	  ++gcov_var.pos;
+	  (void)fgetc(gcov_var.file);
+	}
+      return;
+    }
+#endif
   fseek (gcov_var.file, base, SEEK_SET);
 }
 #endif
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 07/12] gcov: Use xstrdup()
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
                   ` (5 preceding siblings ...)
  2022-03-31 11:35 ` [RFC/gcov 06/12] gcov-tool: Support file input from stdin Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 08/12] gcov: Move prepend to list to read_gcda_file() Sebastian Huber
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

Move duplication of filename to caller and use xstrdup() instead of custom
code.  This helps to reuse read_gcda_file() for other purposes.

libgcc/

	* libgcov-util.c (read_gcda_file): Do not duplicate filename.
	(ftw_read_file): Duplicate filename for read_gcda_file().
---
 libgcc/libgcov-util.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index db157220c9d..ae5712c0138 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -296,16 +296,11 @@ read_gcda_file (const char *filename)
              sizeof (struct gcov_ctr_info) * GCOV_COUNTERS, 1);
 
   obj_info->version = version;
+  obj_info->filename = filename;
   obstack_init (&fn_info);
   num_fn_info = 0;
   curr_fn_info = 0;
-  {
-    size_t len = strlen (filename) + 1;
-    char *str_dup = (char*) xmalloc (len);
 
-    memcpy (str_dup, filename, len);
-    obj_info->filename = str_dup;
-  }
 
   /* Read stamp.  */
   obj_info->stamp = gcov_read_unsigned ();
@@ -415,7 +410,7 @@ ftw_read_file (const char *filename,
   if (verbose)
     fnotice (stderr, "reading file: %s\n", filename);
 
-  obj_info = read_gcda_file (filename);
+  obj_info = read_gcda_file (xstrdup (filename));
   if (!obj_info)
     return 0;
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 08/12] gcov: Move prepend to list to read_gcda_file()
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
                   ` (6 preceding siblings ...)
  2022-03-31 11:35 ` [RFC/gcov 07/12] gcov: Use xstrdup() Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-04-07  8:33   ` Martin Liška
  2022-03-31 11:35 ` [RFC/gcov 09/12] gcov: Move gcov_open() to caller of read_gcda_file() Sebastian Huber
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

This helps to reuse read_gcda_file().

libgcc/

	* libgcov-util.c (read_gcda_file): Prepend new info object to global
	list.
	(ftw_read_file): Remove list append here.
---
 libgcc/libgcov-util.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ae5712c0138..d628c71479e 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -301,6 +301,9 @@ read_gcda_file (const char *filename)
   num_fn_info = 0;
   curr_fn_info = 0;
 
+  /* Prepend to gcov info list */
+  obj_info->next = gcov_info_head;
+  gcov_info_head = obj_info;
 
   /* Read stamp.  */
   obj_info->stamp = gcov_read_unsigned ();
@@ -392,7 +395,6 @@ ftw_read_file (const char *filename,
 {
   int filename_len;
   int suffix_len;
-  struct gcov_info *obj_info;
 
   /* Only read regular files.  */
   if (type != FTW_F)
@@ -410,12 +412,7 @@ ftw_read_file (const char *filename,
   if (verbose)
     fnotice (stderr, "reading file: %s\n", filename);
 
-  obj_info = read_gcda_file (xstrdup (filename));
-  if (!obj_info)
-    return 0;
-
-  obj_info->next = gcov_info_head;
-  gcov_info_head = obj_info;
+  (void)read_gcda_file (xstrdup (filename));
 
   return 0;
 }
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 09/12] gcov: Move gcov_open() to caller of read_gcda_file()
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
                   ` (7 preceding siblings ...)
  2022-03-31 11:35 ` [RFC/gcov 08/12] gcov: Move prepend to list to read_gcda_file() Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 10/12] gcov: Fix integer types in ftw_read_file() Sebastian Huber
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

This allows to reuse read_gcda_file() to read multiple objects from a single
file.

libgcc/

	* libgcov-util.c (read_gcda_file): Do not open file.
	(ftw_read_file): Open file here.
---
 libgcc/libgcov-util.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index d628c71479e..03902ed10b1 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -268,17 +268,10 @@ read_gcda_file (const char *filename)
     k_ctrs_mask[i] = 0;
   k_ctrs_types = 0;
 
-  if (!gcov_open (filename, 1))
-    {
-      fnotice (stderr, "%s:cannot open\n", filename);
-      return NULL;
-    }
-
   /* Read magic.  */
   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
     {
       fnotice (stderr, "%s:not a gcov data file\n", filename);
-      gcov_close ();
       return NULL;
     }
 
@@ -287,7 +280,6 @@ read_gcda_file (const char *filename)
   if (version != GCOV_VERSION)
     {
       fnotice (stderr, "%s:incorrect gcov version %d vs %d \n", filename, version, GCOV_VERSION);
-      gcov_close ();
       return NULL;
     }
 
@@ -379,7 +371,6 @@ read_gcda_file (const char *filename)
     }
 
   read_gcda_finalize (obj_info);
-  gcov_close ();
 
   return obj_info;
 }
@@ -412,7 +403,14 @@ ftw_read_file (const char *filename,
   if (verbose)
     fnotice (stderr, "reading file: %s\n", filename);
 
+  if (!gcov_open (filename, 1))
+    {
+      fnotice (stderr, "%s:cannot open\n", filename);
+      return 0;
+    }
+
   (void)read_gcda_file (xstrdup (filename));
+  gcov_close ();
 
   return 0;
 }
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 10/12] gcov: Fix integer types in ftw_read_file()
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
                   ` (8 preceding siblings ...)
  2022-03-31 11:35 ` [RFC/gcov 09/12] gcov: Move gcov_open() to caller of read_gcda_file() Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-03-31 11:35 ` [RFC/gcov 11/12] gcov: Record EOF error during read Sebastian Huber
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

libgcc/

	* libgcov-util.c (ftw_read_file): Use size_t for strlen() variables.
---
 libgcc/libgcov-util.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 03902ed10b1..622d5a9dc71 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -384,8 +384,8 @@ ftw_read_file (const char *filename,
                const struct stat *status ATTRIBUTE_UNUSED,
                int type)
 {
-  int filename_len;
-  int suffix_len;
+  size_t filename_len;
+  size_t suffix_len;
 
   /* Only read regular files.  */
   if (type != FTW_F)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 11/12] gcov: Record EOF error during read
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
                   ` (9 preceding siblings ...)
  2022-03-31 11:35 ` [RFC/gcov 10/12] gcov: Fix integer types in ftw_read_file() Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-04-07  8:34   ` Martin Liška
  2022-03-31 11:35 ` [RFC/gcov 12/12] gcov-tool: Add merge-stream subcommand Sebastian Huber
  2022-04-07  8:38 ` [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Martin Liška
  12 siblings, 1 reply; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

Use an enum for file error codes.

gcc/

	* gcov-io.cc (gcov_file_error): New enum.
	(gcov_var): Use gcov_file_error enum for the error member.
	(gcov_open): Use GCOV_FILE_NO_ERROR.
	(gcov_close): Use GCOV_FILE_WRITE_ERROR.
	(gcov_write): Likewise.
	(gcov_write_unsigned): Likewise.
	(gcov_write_string): Likewise.
	(gcov_read_bytes): Set error code if EOF is reached.
	(gcov_read_counter): Use GCOV_FILE_COUNTER_OVERFLOW.
---
 gcc/gcov-io.cc | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 177f81166a6..60c762bf3a3 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -29,10 +29,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 static gcov_unsigned_t *gcov_read_words (void *buffer, unsigned);
 
+enum gcov_file_error {
+  GCOV_FILE_COUNTER_OVERFLOW = -1,
+  GCOV_FILE_NO_ERROR = 0,
+  GCOV_FILE_WRITE_ERROR = 1,
+  GCOV_FILE_EOF = 2
+};
+
 struct gcov_var
 {
   FILE *file;
-  int error;			/* < 0 overflow, > 0 disk error.  */
+  enum gcov_file_error error;
   int mode;			/* < 0 writing, > 0 reading.  */
   int endian;			/* Swap endianness.  */
 #ifdef IN_GCOV_TOOL
@@ -113,7 +120,7 @@ gcov_open (const char *name, int mode)
 #endif
 
   gcov_nonruntime_assert (!gcov_var.file);
-  gcov_var.error = 0;
+  gcov_var.error = GCOV_FILE_NO_ERROR;
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
   gcov_var.endian = 0;
 #endif
@@ -217,7 +224,7 @@ gcov_close (void)
   if (gcov_var.file)
     {
       if (fclose (gcov_var.file))
-	gcov_var.error = 1;
+	gcov_var.error = GCOV_FILE_WRITE_ERROR;
 
       gcov_var.file = 0;
     }
@@ -253,7 +260,7 @@ gcov_write (const void *data, unsigned length)
 {
   gcov_unsigned_t r = fwrite (data, length, 1, gcov_var.file);
   if (r != 1)
-    gcov_var.error = 1;
+    gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 
 /* Write unsigned VALUE to coverage file.  */
@@ -263,7 +270,7 @@ gcov_write_unsigned (gcov_unsigned_t value)
 {
   gcov_unsigned_t r = fwrite (&value, sizeof (value), 1, gcov_var.file);
   if (r != 1)
-    gcov_var.error = 1;
+    gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 
 #if !IN_LIBGCOV
@@ -283,7 +290,7 @@ gcov_write_string (const char *string)
     {
       gcov_unsigned_t r = fwrite (string, length, 1, gcov_var.file);
       if (r != 1)
-	gcov_var.error = 1;
+	gcov_var.error = GCOV_FILE_WRITE_ERROR;
     }
 }
 #endif
@@ -385,7 +392,11 @@ gcov_read_bytes (void *buffer, unsigned count)
 
   unsigned read = fread (buffer, count, 1, gcov_var.file);
   if (read != 1)
-    return NULL;
+    {
+      if (feof (gcov_var.file))
+	gcov_var.error = GCOV_FILE_EOF;
+      return NULL;
+    }
 
 #ifdef IN_GCOV_TOOL
   gcov_var.pos += count;
@@ -434,7 +445,7 @@ gcov_read_counter (void)
   if (sizeof (value) > sizeof (gcov_unsigned_t))
     value |= ((gcov_type) from_file (buffer[1])) << 32;
   else if (buffer[1])
-    gcov_var.error = -1;
+    gcov_var.error = GCOV_FILE_COUNTER_OVERFLOW;
 
   return value;
 }
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC/gcov 12/12] gcov-tool: Add merge-stream subcommand
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
                   ` (10 preceding siblings ...)
  2022-03-31 11:35 ` [RFC/gcov 11/12] gcov: Record EOF error during read Sebastian Huber
@ 2022-03-31 11:35 ` Sebastian Huber
  2022-04-07  8:36   ` Martin Liška
  2022-04-07  8:38 ` [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Martin Liška
  12 siblings, 1 reply; 19+ messages in thread
From: Sebastian Huber @ 2022-03-31 11:35 UTC (permalink / raw)
  To: gcc-patches

gcc/

	* gcov-tool.cc (gcov_profile_merge_stream): Declare.
	(print_merge_stream_usage_message): New.
	(merge_stream_usage): Likewise.
	(do_merge_stream): Likewise.
	(print_usage): Call print_merge_stream_usage_message().
	(main): Call do_merge_stream() to execute merge-stream subcommand.

libgcc/

	* libgcov-util.c (consume_stream): New.
	(get_target_profiles_for_merge): Likewise.
	(gcov_profile_merge_stream): Likewise.
---
 gcc/gcov-tool.cc      | 76 ++++++++++++++++++++++++++++++++++++++++
 libgcc/libgcov-util.c | 80 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 156 insertions(+)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index d712715cf7e..d8572b184e9 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
 					     struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge_stream (const char *, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -229,6 +230,78 @@ do_merge (int argc, char **argv)
   return profile_merge (argv[optind], argv[optind+1], output_dir, w1, w2);
 }
 
+/* Usage message for profile merge-stream.  */
+
+static void
+print_merge_stream_usage_message (int error_p)
+{
+  FILE *file = error_p ? stderr : stdout;
+
+  fnotice (file, "  merge-stream [options] [stream-file]  Merge coverage stream file (or stdin)\n"
+		 "                                        and coverage file contents\n");
+  fnotice (file, "    -v, --verbose                       Verbose mode\n");
+  fnotice (file, "    -w, --weight <w1,w2>                Set weights (float point values)\n");
+}
+
+static const struct option merge_stream_options[] =
+{
+  { "verbose",                no_argument,       NULL, 'v' },
+  { "weight",                 required_argument, NULL, 'w' },
+  { 0, 0, 0, 0 }
+};
+
+/* Print merge-stream usage and exit.  */
+
+static void ATTRIBUTE_NORETURN
+merge_stream_usage (void)
+{
+  fnotice (stderr, "Merge-stream subcomand usage:");
+  print_merge_stream_usage_message (true);
+  exit (FATAL_EXIT_CODE);
+}
+
+/* Driver for profile merge-stream sub-command.  */
+
+static int
+do_merge_stream (int argc, char **argv)
+{
+  int opt;
+  int w1 = 1, w2 = 1;
+  struct gcov_info *merged_profile;
+
+  optind = 0;
+  while ((opt = getopt_long (argc, argv, "vw:",
+			     merge_stream_options, NULL)) != -1)
+    {
+      switch (opt)
+	{
+	case 'v':
+	  verbose = true;
+	  gcov_set_verbose ();
+	  break;
+	case 'w':
+	  sscanf (optarg, "%d,%d", &w1, &w2);
+	  if (w1 < 0 || w2 < 0)
+	    fatal_error (input_location, "weights need to be non-negative");
+	  break;
+	default:
+	  merge_stream_usage ();
+	}
+    }
+
+  if (argc - optind > 1)
+    merge_stream_usage ();
+
+  merged_profile = gcov_profile_merge_stream (argv[optind], w1, w2);
+
+  if (merged_profile)
+    gcov_do_dump (merged_profile, 0, -1);
+  else if (verbose)
+    fnotice (stdout, "no profile files were merged\n");
+
+  return 0;
+}
+
 /* If N_VAL is no-zero, normalize the profile by setting the largest counter
    counter value to N_VAL and scale others counters proportionally.
    Otherwise, multiply the all counters by SCALE.  */
@@ -505,6 +578,7 @@ print_usage (int error_p)
   fnotice (file, "  -h, --help                            Print this help, then exit\n");
   fnotice (file, "  -v, --version                         Print version number, then exit\n");
   print_merge_usage_message (error_p);
+  print_merge_stream_usage_message (error_p);
   print_rewrite_usage_message (error_p);
   print_overlap_usage_message (error_p);
   fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
@@ -594,6 +668,8 @@ main (int argc, char **argv)
 
   if (!strcmp (sub_command, "merge"))
     return do_merge (argc - optind, argv + optind);
+  else if (!strcmp (sub_command, "merge-stream"))
+    return do_merge_stream (argc - optind, argv + optind);
   else if (!strcmp (sub_command, "rewrite"))
     return do_rewrite (argc - optind, argv + optind);
   else if (!strcmp (sub_command, "overlap"))
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 622d5a9dc71..0fe60528b48 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -735,6 +735,86 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info *src_profile
   return tgt_profile;
 }
 
+struct gcov_info *
+consume_stream (const char *filename)
+{
+  read_profile_dir_init ();
+
+  while (true)
+    {
+      unsigned version;
+      const char *filename_of_info;
+      struct gcov_info *obj_info;
+
+      if (!gcov_magic (gcov_read_unsigned (), GCOV_FILENAME_MAGIC))
+	{
+	  if (gcov_is_error() != 2)
+	    fnotice (stderr, "%s:not a gcfn stream\n", filename);
+	  break;
+	}
+
+      version = gcov_read_unsigned ();
+      if (version != GCOV_VERSION)
+	{
+	  fnotice (stderr, "%s:incorrect gcov version %d vs %d \n",
+		   filename, version, GCOV_VERSION);
+	  break;
+	}
+
+      filename_of_info = gcov_read_string ();
+      if (!filename_of_info)
+	{
+	  fnotice (stderr, "%s:no filename in gcfn stream\n",
+		   filename);
+	  break;
+	}
+
+      obj_info = read_gcda_file (filename);
+      if (!obj_info)
+	break;
+
+      obj_info->filename = filename_of_info;
+    }
+
+  return gcov_info_head;
+}
+
+struct gcov_info *
+get_target_profiles_for_merge (struct gcov_info *src_profile)
+{
+  struct gcov_info *gi_ptr;
+
+  read_profile_dir_init ();
+
+  for (gi_ptr = src_profile; gi_ptr; gi_ptr = gi_ptr->next)
+    if (gcov_open (gi_ptr->filename, 1))
+      {
+	(void)read_gcda_file (gi_ptr->filename);
+	gcov_close ();
+      }
+
+  return gcov_info_head;
+}
+
+struct gcov_info *
+gcov_profile_merge_stream (const char *filename, int w1, int w2)
+{
+  struct gcov_info *tgt_profile;
+  struct gcov_info *src_profile;
+
+  if (!gcov_open (filename, 1))
+    {
+      fnotice (stderr, "%s:cannot open\n", filename);
+      return NULL;
+    }
+
+  src_profile = consume_stream (filename ? filename : "<stdin>");
+  gcov_close ();
+  tgt_profile = get_target_profiles_for_merge (src_profile);
+
+  return gcov_profile_merge (tgt_profile, src_profile, w1, w2);
+}
+
 typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*);
 
 /* Performing FN upon arc counters.  */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC/gcov 06/12] gcov-tool: Support file input from stdin
  2022-03-31 11:35 ` [RFC/gcov 06/12] gcov-tool: Support file input from stdin Sebastian Huber
@ 2022-04-07  8:32   ` Martin Liška
  0 siblings, 0 replies; 19+ messages in thread
From: Martin Liška @ 2022-04-07  8:32 UTC (permalink / raw)
  To: Sebastian Huber, gcc-patches

On 3/31/22 13:35, Sebastian Huber wrote:
> gcc/
> 
> 	* gcov-io.cc (GCOV_MODE_STDIN): Define.
> 	(gcov_position): For gcov-tool, return calculated position if file is
> 	stdin.
> 	(gcov_open):  For gcov-tool, use stdin if filename is NULL.
> 	(gcov_close): For gcov-tool, do not close stdin.
> 	(gcov_read_bytes): For gcov-tool, update position if file is stdin.
> 	(gcov_sync): For gcov-tool, discard input if file is stdin.
> ---
>   gcc/gcov-io.cc | 38 ++++++++++++++++++++++++++++++++++++++
>   1 file changed, 38 insertions(+)
> 
> diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
> index fee3130f94a..177f81166a6 100644
> --- a/gcc/gcov-io.cc
> +++ b/gcc/gcov-io.cc
> @@ -35,8 +35,13 @@ struct gcov_var
>     int error;			/* < 0 overflow, > 0 disk error.  */
>     int mode;			/* < 0 writing, > 0 reading.  */
>     int endian;			/* Swap endianness.  */
> +#ifdef IN_GCOV_TOOL
> +  gcov_position_t pos;		/* File position for stdin support. */

One more space after dot.

> +#endif
>   } gcov_var;
>   
> +#define GCOV_MODE_STDIN 2
> +
>   /* Save the current position in the gcov file.  */
>   /* We need to expose this function when compiling for gcov-tool.  */
>   #ifndef IN_GCOV_TOOL
> @@ -45,6 +50,10 @@ static inline
>   gcov_position_t
>   gcov_position (void)
>   {
> +#ifdef IN_GCOV_TOOL
> +  if (gcov_var.mode == GCOV_MODE_STDIN)
> +    return gcov_var.pos;
> +#endif
>     return ftell (gcov_var.file);
>   }
>   
> @@ -108,6 +117,16 @@ gcov_open (const char *name, int mode)
>   #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
>     gcov_var.endian = 0;
>   #endif
> +#ifdef IN_GCOV_TOOL
> +  gcov_var.pos = 0;
> +  if (!name)
> +    {
> +      gcov_nonruntime_assert (gcov_var.mode > 0);
> +      gcov_var.file = stdin;
> +      gcov_var.mode = GCOV_MODE_STDIN;
> +      return 1;
> +    }
> +#endif
>   #if GCOV_LOCKED
>     if (mode > 0)
>       {
> @@ -190,6 +209,11 @@ gcov_open (const char *name, int mode)
>   GCOV_LINKAGE int
>   gcov_close (void)
>   {
> +#ifdef IN_GCOV_TOOL
> +  if (gcov_var.file == stdin)
> +    gcov_var.file = 0;
> +  else
> +#endif
>     if (gcov_var.file)
>       {
>         if (fclose (gcov_var.file))
> @@ -363,6 +387,9 @@ gcov_read_bytes (void *buffer, unsigned count)
>     if (read != 1)
>       return NULL;
>   
> +#ifdef IN_GCOV_TOOL
> +  gcov_var.pos += count;
> +#endif
>     return buffer;
>   }
>   
> @@ -499,6 +526,17 @@ gcov_sync (gcov_position_t base, gcov_unsigned_t length)
>   {
>     gcov_nonruntime_assert (gcov_var.mode > 0);
>     base += length;
> +#ifdef IN_GCOV_TOOL
> +  if (gcov_var.mode == GCOV_MODE_STDIN)
> +    {
> +      while (gcov_var.pos < base)
> +	{
> +	  ++gcov_var.pos;
> +	  (void)fgetc(gcov_var.file);

A space after fgetc, please.

Martin

> +	}
> +      return;
> +    }
> +#endif
>     fseek (gcov_var.file, base, SEEK_SET);
>   }
>   #endif


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC/gcov 08/12] gcov: Move prepend to list to read_gcda_file()
  2022-03-31 11:35 ` [RFC/gcov 08/12] gcov: Move prepend to list to read_gcda_file() Sebastian Huber
@ 2022-04-07  8:33   ` Martin Liška
  0 siblings, 0 replies; 19+ messages in thread
From: Martin Liška @ 2022-04-07  8:33 UTC (permalink / raw)
  To: Sebastian Huber, gcc-patches

On 3/31/22 13:35, Sebastian Huber wrote:
> |+ /* Prepend to gcov info list */|

Please add dot and 2 spaces.

Martin

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC/gcov 11/12] gcov: Record EOF error during read
  2022-03-31 11:35 ` [RFC/gcov 11/12] gcov: Record EOF error during read Sebastian Huber
@ 2022-04-07  8:34   ` Martin Liška
  0 siblings, 0 replies; 19+ messages in thread
From: Martin Liška @ 2022-04-07  8:34 UTC (permalink / raw)
  To: Sebastian Huber, gcc-patches

On 3/31/22 13:35, Sebastian Huber wrote:
> |+enum gcov_file_error {|

Please put the brace to the next line and comment the enum type.

Martin

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC/gcov 12/12] gcov-tool: Add merge-stream subcommand
  2022-03-31 11:35 ` [RFC/gcov 12/12] gcov-tool: Add merge-stream subcommand Sebastian Huber
@ 2022-04-07  8:36   ` Martin Liška
  0 siblings, 0 replies; 19+ messages in thread
From: Martin Liška @ 2022-04-07  8:36 UTC (permalink / raw)
  To: Sebastian Huber, gcc-patches

On 3/31/22 13:35, Sebastian Huber wrote:
> gcc/
> 
> 	* gcov-tool.cc (gcov_profile_merge_stream): Declare.
> 	(print_merge_stream_usage_message): New.
> 	(merge_stream_usage): Likewise.
> 	(do_merge_stream): Likewise.
> 	(print_usage): Call print_merge_stream_usage_message().
> 	(main): Call do_merge_stream() to execute merge-stream subcommand.
> 
> libgcc/
> 
> 	* libgcov-util.c (consume_stream): New.
> 	(get_target_profiles_for_merge): Likewise.
> 	(gcov_profile_merge_stream): Likewise.
> ---
>   gcc/gcov-tool.cc      | 76 ++++++++++++++++++++++++++++++++++++++++
>   libgcc/libgcov-util.c | 80 +++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 156 insertions(+)
> 
> diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
> index d712715cf7e..d8572b184e9 100644
> --- a/gcc/gcov-tool.cc
> +++ b/gcc/gcov-tool.cc
> @@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>   
>   extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
>   					     struct gcov_info*, int, int);
> +extern struct gcov_info *gcov_profile_merge_stream (const char *, int, int);
>   extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
>   extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
>   extern int gcov_profile_scale (struct gcov_info*, float, int, int);
> @@ -229,6 +230,78 @@ do_merge (int argc, char **argv)
>     return profile_merge (argv[optind], argv[optind+1], output_dir, w1, w2);
>   }
>   
> +/* Usage message for profile merge-stream.  */
> +
> +static void
> +print_merge_stream_usage_message (int error_p)
> +{
> +  FILE *file = error_p ? stderr : stdout;
> +
> +  fnotice (file, "  merge-stream [options] [stream-file]  Merge coverage stream file (or stdin)\n"
> +		 "                                        and coverage file contents\n");
> +  fnotice (file, "    -v, --verbose                       Verbose mode\n");
> +  fnotice (file, "    -w, --weight <w1,w2>                Set weights (float point values)\n");
> +}
> +
> +static const struct option merge_stream_options[] =
> +{
> +  { "verbose",                no_argument,       NULL, 'v' },
> +  { "weight",                 required_argument, NULL, 'w' },
> +  { 0, 0, 0, 0 }
> +};
> +
> +/* Print merge-stream usage and exit.  */
> +
> +static void ATTRIBUTE_NORETURN
> +merge_stream_usage (void)
> +{
> +  fnotice (stderr, "Merge-stream subcomand usage:");
> +  print_merge_stream_usage_message (true);
> +  exit (FATAL_EXIT_CODE);
> +}
> +
> +/* Driver for profile merge-stream sub-command.  */
> +
> +static int
> +do_merge_stream (int argc, char **argv)
> +{
> +  int opt;
> +  int w1 = 1, w2 = 1;
> +  struct gcov_info *merged_profile;
> +
> +  optind = 0;
> +  while ((opt = getopt_long (argc, argv, "vw:",
> +			     merge_stream_options, NULL)) != -1)
> +    {
> +      switch (opt)
> +	{
> +	case 'v':
> +	  verbose = true;
> +	  gcov_set_verbose ();
> +	  break;
> +	case 'w':
> +	  sscanf (optarg, "%d,%d", &w1, &w2);
> +	  if (w1 < 0 || w2 < 0)
> +	    fatal_error (input_location, "weights need to be non-negative");
> +	  break;
> +	default:
> +	  merge_stream_usage ();
> +	}
> +    }
> +
> +  if (argc - optind > 1)
> +    merge_stream_usage ();
> +
> +  merged_profile = gcov_profile_merge_stream (argv[optind], w1, w2);
> +
> +  if (merged_profile)
> +    gcov_do_dump (merged_profile, 0, -1);
> +  else if (verbose)
> +    fnotice (stdout, "no profile files were merged\n");
> +
> +  return 0;
> +}
> +
>   /* If N_VAL is no-zero, normalize the profile by setting the largest counter
>      counter value to N_VAL and scale others counters proportionally.
>      Otherwise, multiply the all counters by SCALE.  */
> @@ -505,6 +578,7 @@ print_usage (int error_p)
>     fnotice (file, "  -h, --help                            Print this help, then exit\n");
>     fnotice (file, "  -v, --version                         Print version number, then exit\n");
>     print_merge_usage_message (error_p);
> +  print_merge_stream_usage_message (error_p);
>     print_rewrite_usage_message (error_p);
>     print_overlap_usage_message (error_p);
>     fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
> @@ -594,6 +668,8 @@ main (int argc, char **argv)
>   
>     if (!strcmp (sub_command, "merge"))
>       return do_merge (argc - optind, argv + optind);
> +  else if (!strcmp (sub_command, "merge-stream"))
> +    return do_merge_stream (argc - optind, argv + optind);
>     else if (!strcmp (sub_command, "rewrite"))
>       return do_rewrite (argc - optind, argv + optind);
>     else if (!strcmp (sub_command, "overlap"))
> diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
> index 622d5a9dc71..0fe60528b48 100644
> --- a/libgcc/libgcov-util.c
> +++ b/libgcc/libgcov-util.c
> @@ -735,6 +735,86 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info *src_profile
>     return tgt_profile;
>   }

Please document the new added functions below.

>   
> +struct gcov_info *
> +consume_stream (const char *filename)
> +{
> +  read_profile_dir_init ();
> +
> +  while (true)
> +    {
> +      unsigned version;
> +      const char *filename_of_info;
> +      struct gcov_info *obj_info;
> +
> +      if (!gcov_magic (gcov_read_unsigned (), GCOV_FILENAME_MAGIC))
> +	{
> +	  if (gcov_is_error() != 2)

A space after ().

Martin

> +	    fnotice (stderr, "%s:not a gcfn stream\n", filename);
> +	  break;
> +	}
> +
> +      version = gcov_read_unsigned ();
> +      if (version != GCOV_VERSION)
> +	{
> +	  fnotice (stderr, "%s:incorrect gcov version %d vs %d \n",
> +		   filename, version, GCOV_VERSION);
> +	  break;
> +	}
> +
> +      filename_of_info = gcov_read_string ();
> +      if (!filename_of_info)
> +	{
> +	  fnotice (stderr, "%s:no filename in gcfn stream\n",
> +		   filename);
> +	  break;
> +	}
> +
> +      obj_info = read_gcda_file (filename);
> +      if (!obj_info)
> +	break;
> +
> +      obj_info->filename = filename_of_info;
> +    }
> +
> +  return gcov_info_head;
> +}
> +
> +struct gcov_info *
> +get_target_profiles_for_merge (struct gcov_info *src_profile)
> +{
> +  struct gcov_info *gi_ptr;
> +
> +  read_profile_dir_init ();
> +
> +  for (gi_ptr = src_profile; gi_ptr; gi_ptr = gi_ptr->next)
> +    if (gcov_open (gi_ptr->filename, 1))
> +      {
> +	(void)read_gcda_file (gi_ptr->filename);
> +	gcov_close ();
> +      }
> +
> +  return gcov_info_head;
> +}
> +
> +struct gcov_info *
> +gcov_profile_merge_stream (const char *filename, int w1, int w2)
> +{
> +  struct gcov_info *tgt_profile;
> +  struct gcov_info *src_profile;
> +
> +  if (!gcov_open (filename, 1))
> +    {
> +      fnotice (stderr, "%s:cannot open\n", filename);
> +      return NULL;
> +    }
> +
> +  src_profile = consume_stream (filename ? filename : "<stdin>");
> +  gcov_close ();
> +  tgt_profile = get_target_profiles_for_merge (src_profile);
> +
> +  return gcov_profile_merge (tgt_profile, src_profile, w1, w2);
> +}
> +
>   typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*);
>   
>   /* Performing FN upon arc counters.  */


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool
  2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
                   ` (11 preceding siblings ...)
  2022-03-31 11:35 ` [RFC/gcov 12/12] gcov-tool: Add merge-stream subcommand Sebastian Huber
@ 2022-04-07  8:38 ` Martin Liška
  2022-04-07  9:05   ` Sebastian Huber
  12 siblings, 1 reply; 19+ messages in thread
From: Martin Liška @ 2022-04-07  8:38 UTC (permalink / raw)
  To: Sebastian Huber, gcc-patches

On 3/31/22 13:35, Sebastian Huber wrote:
> This patch set is a proof of concept.
> 
> The aim is to better support gcov in free-standing environments. For example,
> you can run a test executable which dumps all gcov info objects in a serial
> data stream using __gcov_info_to_gcda() and the new __gcov_filename_to_gcfn().
> It could be encoded as base64. It could be also compressed. On the host you
> unpack the encoded data stream and feed it into gcov-tool using the new
> "merge-stream" subcommand:

Hello.

The patch set is approved with the nits provided. Please install the patches
once stage1 opens.

> 
> gcov-tool --help
> Usage: gcov-tool [OPTION]... SUB_COMMAND [OPTION]...
> 
> Offline tool to handle gcda counts
> 
>    -h, --help                            Print this help, then exit
>    -v, --version                         Print version number, then exit
>    merge-stream [options] [stream-file]  Merge coverage stream file (or stdin)
>                                          and coverage file contents
>      -v, --verbose                       Verbose mode
>      -w, --weight <w1,w2>                Set weights (float point values)
> 
> Example:
> 
> base64 -d log.txt | gcov-tool merge-stream
> 
> The patch set does not change the format of gcda files.
> 
> TODO:
> 
> * Documentation

I would install the patches with documentation change bits.

> * Tests

Tests can be added after that.

Thank you for the functionality.
Cheers,
Martin

> 
> Sebastian Huber (12):
>    gcov-tool: Allow merging of empty profile lists
>    gcov: Add mode to all gcov_open()
>    gcov: Add open mode parameter to gcov_do_dump()
>    gcov: Make gcov_seek() static
>    gcov: Add __gcov_filename_to_gcfn()
>    gcov-tool: Support file input from stdin
>    gcov: Use xstrdup()
>    gcov: Move prepend to list to read_gcda_file()
>    gcov: Move gcov_open() to caller of read_gcda_file()
>    gcov: Fix integer types in ftw_read_file()
>    gcov: Record EOF error during read
>    gcov-tool: Add merge-stream subcommand
> 
>   gcc/gcov-io.cc                 |  76 ++++++++++++++-----
>   gcc/gcov-io.h                  |  35 +++++----
>   gcc/gcov-tool.cc               | 107 +++++++++++++++++++++-----
>   libgcc/gcov.h                  |  17 ++++-
>   libgcc/libgcov-driver-system.c |   7 +-
>   libgcc/libgcov-driver.c        |  42 ++++++++--
>   libgcc/libgcov-util.c          | 135 +++++++++++++++++++++++++--------
>   libgcc/libgcov.h               |   3 -
>   8 files changed, 326 insertions(+), 96 deletions(-)
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool
  2022-04-07  8:38 ` [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Martin Liška
@ 2022-04-07  9:05   ` Sebastian Huber
  0 siblings, 0 replies; 19+ messages in thread
From: Sebastian Huber @ 2022-04-07  9:05 UTC (permalink / raw)
  To: Martin Liška, gcc-patches

Hello Martin,

thanks for the review. I am not really used to write func ().

On 07/04/2022 10:38, Martin Liška wrote:
>>
>> TODO:
>>
>> * Documentation
> 
> I would install the patches with documentation change bits.

Ok, I will add some documentation changes and send them with a v2 of the 
patch set after stage 0 opens.

I would like to add a chapter about the use of gcov in systems without a 
file system.

> 
>> * Tests
> 
> Tests can be added after that.

Ok, good.

-- 
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] 19+ messages in thread

end of thread, other threads:[~2022-04-07  9:05 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 01/12] gcov-tool: Allow merging of empty profile lists Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 02/12] gcov: Add mode to all gcov_open() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 03/12] gcov: Add open mode parameter to gcov_do_dump() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 04/12] gcov: Make gcov_seek() static Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 05/12] gcov: Add __gcov_filename_to_gcfn() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 06/12] gcov-tool: Support file input from stdin Sebastian Huber
2022-04-07  8:32   ` Martin Liška
2022-03-31 11:35 ` [RFC/gcov 07/12] gcov: Use xstrdup() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 08/12] gcov: Move prepend to list to read_gcda_file() Sebastian Huber
2022-04-07  8:33   ` Martin Liška
2022-03-31 11:35 ` [RFC/gcov 09/12] gcov: Move gcov_open() to caller of read_gcda_file() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 10/12] gcov: Fix integer types in ftw_read_file() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 11/12] gcov: Record EOF error during read Sebastian Huber
2022-04-07  8:34   ` Martin Liška
2022-03-31 11:35 ` [RFC/gcov 12/12] gcov-tool: Add merge-stream subcommand Sebastian Huber
2022-04-07  8:36   ` Martin Liška
2022-04-07  8:38 ` [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Martin Liška
2022-04-07  9:05   ` 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).