From a978e26b8338e044dbc5e0f4624f2fe047eec5df Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor <iant@golang.org>
Date: Thu, 5 Oct 2017 16:39:38 +0000
Subject: [PATCH] elf.c (elf_zlib_fetch): Change pval argument to uint64_t *.

	* elf.c (elf_zlib_fetch): Change pval argument to uint64_t *.
	Read a four byte integer.
	(elf_zlib_inflate): Change val to uint64_t.  Align pin to a 32-bit
	boundary before ever calling elf_zlib_fetch.
	* ztest.c (test_large): Simplify print statements a bit.

From-SVN: r253456
---
 libbacktrace/ChangeLog |  8 +++++++
 libbacktrace/elf.c     | 49 +++++++++++++++++++++++++++++++-----------
 libbacktrace/ztest.c   |  6 +++---
 3 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index 27024b7ea40f..7aadc7353ef2 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,3 +1,11 @@
+2017-10-05  Ian Lance Taylor  <iant@golang.org>
+
+	* elf.c (elf_zlib_fetch): Change pval argument to uint64_t *.
+	Read a four byte integer.
+	(elf_zlib_inflate): Change val to uint64_t.  Align pin to a 32-bit
+	boundary before ever calling elf_zlib_fetch.
+	* ztest.c (test_large): Simplify print statements a bit.
+
 2017-10-02  Ian Lance Taylor  <iant@golang.org>
 
 	* ztest.c: #include <errno.h>.
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index bfedca9a9cbb..06823fcf59b6 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -1031,11 +1031,12 @@ elf_zlib_failed(void)
 
 static int
 elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend,
-		uint32_t *pval, unsigned int *pbits)
+		uint64_t *pval, unsigned int *pbits)
 {
   unsigned int bits;
   const unsigned char *pin;
-  uint32_t val;
+  uint64_t val;
+  uint32_t next;
 
   bits = *pbits;
   if (bits >= 15)
@@ -1043,20 +1044,25 @@ elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend,
   pin = *ppin;
   val = *pval;
 
-  if (unlikely (pinend - pin < 2))
+  if (unlikely (pinend - pin < 4))
     {
       elf_zlib_failed ();
       return 0;
     }
-  val |= pin[0] << bits;
-  val |= pin[1] << (bits + 8);
-  bits += 16;
-  pin += 2;
 
-  /* We will need the next two bytes soon.  We ask for high temporal
-     locality because we will need the whole cache line soon.  */
-  __builtin_prefetch (pin, 0, 3);
-  __builtin_prefetch (pin + 1, 0, 3);
+  /* We've ensured that PIN is aligned.  */
+  next = *(const uint32_t *)pin;
+
+#if __BYTE_ORDER == __ORDER_BIG_ENDIAN
+  next = __builtin_bswap32 (next);
+#endif
+
+  val |= (uint64_t)next << bits;
+  bits += 32;
+  pin += 4;
+
+  /* We will need the next four bytes soon.  */
+  __builtin_prefetch (pin, 0, 0);
 
   *ppin = pin;
   *pval = val;
@@ -1566,7 +1572,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
   poutend = pout + sout;
   while ((pinend - pin) > 4)
     {
-      uint32_t val;
+      uint64_t val;
       unsigned int bits;
       int last;
 
@@ -1601,10 +1607,19 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 	}
       pin += 2;
 
-      /* Read blocks until one is marked last.  */
+      /* Align PIN to a 32-bit boundary.  */
 
       val = 0;
       bits = 0;
+      while ((((uintptr_t) pin) & 3) != 0)
+	{
+	  val |= (uint64_t)*pin << bits;
+	  bits += 8;
+	  ++pin;
+	}
+
+      /* Read blocks until one is marked last.  */
+
       last = 0;
 
       while (!last)
@@ -1671,6 +1686,14 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 	      pout += len;
 	      pin += len;
 
+	      /* Align PIN.  */
+	      while ((((uintptr_t) pin) & 3) != 0)
+		{
+		  val |= (uint64_t)*pin << bits;
+		  bits += 8;
+		  ++pin;
+		}
+
 	      /* Go around to read the next block.  */
 	      continue;
 	    }
diff --git a/libbacktrace/ztest.c b/libbacktrace/ztest.c
index e2ab524825ca..7226d6a0a36c 100644
--- a/libbacktrace/ztest.c
+++ b/libbacktrace/ztest.c
@@ -432,9 +432,9 @@ test_large (struct backtrace_state *state)
   ctime = average_time (ctimes, trials);
   ztime = average_time (ztimes, trials);
 
-  printf ("backtrace time: %zu ns\n", ctime);
-  printf ("zlib time:    : %zu ns\n", ztime);
-  printf ("percentage    : %g\n", (double) ztime / (double) ctime);
+  printf ("backtrace: %zu ns\n", ctime);
+  printf ("zlib     : %zu ns\n", ztime);
+  printf ("ratio    : %g\n", (double) ztime / (double) ctime);
 
   return;
 
-- 
GitLab