From 17d1594bfe08f3c768e024b180816cbe37ac08ac Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Thu, 28 May 2020 08:16:58 +0200
Subject: [PATCH] gcov-tool: Flexible endian adjustment for merging coverage
 data

gcc/ChangeLog:
2020-05-27  Dong JianQiang  <dongjianqiang2@huawei.com>

	PR gcov-profile/95332
	* gcov-io.c (gcov_var::endian): Move field.
	(from_file): Add IN_GCOV_TOOL check.
	* gcov-io.h (gcov_magic): Ditto.

libgcc/ChangeLog:
2020-05-27  Dong JianQiang  <dongjianqiang2@huawei.com>

	PR gcov-profile/95332
	* libgcov-util.c (read_gcda_file): Call gcov_magic.
	* libgcov.h (gcov_magic): Disable GCC poison.
---
 gcc/gcov-io.c         | 6 +++---
 gcc/gcov-io.h         | 3 +++
 libgcc/libgcov-util.c | 5 ++---
 libgcc/libgcov.h      | 2 +-
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c
index 213c413b3a01..ac60f9baf47e 100644
--- a/gcc/gcov-io.c
+++ b/gcc/gcov-io.c
@@ -48,6 +48,7 @@ struct gcov_var
   unsigned overread;		/* Number of words overread.  */
   int error;			/* < 0 overflow, > 0 disk error.  */
   int mode;	                /* < 0 writing, > 0 reading */
+  int endian;			/* Swap endianness.  */
 #if IN_LIBGCOV
   /* Holds one block plus 4 bytes, thus all coverage reads & writes
      fit within this buffer and we always can transfer GCOV_BLOCK_SIZE
@@ -55,7 +56,6 @@ struct gcov_var
      or 8 byte objects.  */
   gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1];
 #else
-  int endian;			/* Swap endianness.  */
   /* Holds a variable length block, as the compiler can write
      strings and needs to backtrack.  */
   size_t alloc;
@@ -100,7 +100,7 @@ gcov_rewrite (void)
 
 static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
 {
-#if !IN_LIBGCOV
+#if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
   if (gcov_var.endian)
     {
       value = (value >> 16) | (value << 16);
@@ -222,7 +222,7 @@ gcov_close (void)
   return gcov_var.error;
 }
 
-#if !IN_LIBGCOV
+#if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
 /* Check if MAGIC is EXPECTED. Use it to determine endianness of the
    file. Returns +1 for same endian, -1 for other endian and zero for
    not EXPECTED.  */
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index ef888f3ff98b..8cb68aaf42d1 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -332,6 +332,9 @@ struct gcov_summary
 
 #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
 
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 449638bc4b66..fff54c6a3f6b 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -261,7 +261,7 @@ read_gcda_file (const char *filename)
 {
   unsigned tags[4];
   unsigned depth = 0;
-  unsigned magic, version;
+  unsigned version;
   struct gcov_info *obj_info;
   int i;
 
@@ -276,8 +276,7 @@ read_gcda_file (const char *filename)
     }
 
   /* Read magic.  */
-  magic = gcov_read_unsigned ();
-  if (magic != GCOV_DATA_MAGIC)
+  if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
     {
       fnotice (stderr, "%s:not a gcov data file\n", filename);
       gcov_close ();
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 104b80bdcbb0..b248690086ea 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -147,7 +147,7 @@ extern struct gcov_info *gcov_list;
 
 /* Poison these, so they don't accidentally slip in.  */
 #pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length
-#pragma GCC poison gcov_time gcov_magic
+#pragma GCC poison gcov_time
 
 #ifdef HAVE_GAS_HIDDEN
 #define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
-- 
GitLab