Mark Wielaard a8d9e8
From a2246aaad96e062eb3bab55af9526aaa70adcfd0 Mon Sep 17 00:00:00 2001
Mark Wielaard a8d9e8
From: Dima Kogan <dkogan@debian.org>
Mark Wielaard a8d9e8
Date: Fri, 8 Dec 2017 01:45:10 -0800
Mark Wielaard a8d9e8
Subject: [PATCH 1/2] libdw: dwarf_aggregate_size() works with
Mark Wielaard a8d9e8
 multi-dimensional arrays
Mark Wielaard a8d9e8
Mark Wielaard a8d9e8
If we have a multidimensional array of dimensions (a,b,c) the number of elements
Mark Wielaard a8d9e8
should be a*b*c, but prior to this patch dwarf_aggregate_size() would report
Mark Wielaard a8d9e8
a+b+c instead.
Mark Wielaard a8d9e8
Mark Wielaard a8d9e8
This patch fixes the bug and adds a test that demonstrates the bug (the test
Mark Wielaard a8d9e8
fails without the functional part of this patch).
Mark Wielaard a8d9e8
Mark Wielaard a8d9e8
Fixes: https://sourceware.org/bugzilla/show_bug.cgi?id=22546
Mark Wielaard a8d9e8
Mark Wielaard a8d9e8
Signed-off-by: Dima Kogan <dima@secretsauce.net>
Mark Wielaard a8d9e8
---
Mark Wielaard a8d9e8
 libdw/ChangeLog              |   5 +++++
Mark Wielaard a8d9e8
 libdw/dwarf_aggregate_size.c |  43 ++++++++++++++++++++++---------------------
Mark Wielaard a8d9e8
 tests/ChangeLog              |   6 ++++++
Mark Wielaard a8d9e8
 tests/run-aggregate-size.sh  |   2 ++
Mark Wielaard a8d9e8
 tests/run-peel-type.sh       |   1 +
Mark Wielaard a8d9e8
 tests/testfile-sizes3.o.bz2  | Bin 1147 -> 1208 bytes
Mark Wielaard a8d9e8
 6 files changed, 36 insertions(+), 21 deletions(-)
Mark Wielaard a8d9e8
Mark Wielaard a8d9e8
diff --git a/libdw/dwarf_aggregate_size.c b/libdw/dwarf_aggregate_size.c
Mark Wielaard a8d9e8
index 838468d..3010c0a 100644
Mark Wielaard a8d9e8
--- a/libdw/dwarf_aggregate_size.c
Mark Wielaard a8d9e8
+++ b/libdw/dwarf_aggregate_size.c
Mark Wielaard a8d9e8
@@ -63,7 +63,7 @@ array_size (Dwarf_Die *die, Dwarf_Word *size,
Mark Wielaard a8d9e8
     return -1;
Mark Wielaard a8d9e8
 
Mark Wielaard a8d9e8
   bool any = false;
Mark Wielaard a8d9e8
-  Dwarf_Word total = 0;
Mark Wielaard a8d9e8
+  Dwarf_Word count_total = 1;
Mark Wielaard a8d9e8
   do
Mark Wielaard a8d9e8
     {
Mark Wielaard a8d9e8
       Dwarf_Word count;
Mark Wielaard a8d9e8
@@ -134,34 +134,35 @@ array_size (Dwarf_Die *die, Dwarf_Word *size,
Mark Wielaard a8d9e8
 	  continue;
Mark Wielaard a8d9e8
 	}
Mark Wielaard a8d9e8
 
Mark Wielaard a8d9e8
-      /* This is a subrange_type or enumeration_type and we've set COUNT.
Mark Wielaard a8d9e8
-	 Now determine the stride for this array dimension.  */
Mark Wielaard a8d9e8
-      Dwarf_Word stride = eltsize;
Mark Wielaard a8d9e8
-      if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_byte_stride,
Mark Wielaard a8d9e8
-					attr_mem) != NULL)
Mark Wielaard a8d9e8
-	{
Mark Wielaard a8d9e8
-	  if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
Mark Wielaard a8d9e8
-	    return -1;
Mark Wielaard a8d9e8
-	}
Mark Wielaard a8d9e8
-      else if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_bit_stride,
Mark Wielaard a8d9e8
-					     attr_mem) != NULL)
Mark Wielaard a8d9e8
-	{
Mark Wielaard a8d9e8
-	  if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
Mark Wielaard a8d9e8
-	    return -1;
Mark Wielaard a8d9e8
-	  if (stride % 8) 	/* XXX maybe compute in bits? */
Mark Wielaard a8d9e8
-	    return -1;
Mark Wielaard a8d9e8
-	  stride /= 8;
Mark Wielaard a8d9e8
-	}
Mark Wielaard a8d9e8
+      count_total *= count;
Mark Wielaard a8d9e8
 
Mark Wielaard a8d9e8
       any = true;
Mark Wielaard a8d9e8
-      total += stride * count;
Mark Wielaard a8d9e8
     }
Mark Wielaard a8d9e8
   while (INTUSE(dwarf_siblingof) (&child, &child) == 0);
Mark Wielaard a8d9e8
 
Mark Wielaard a8d9e8
   if (!any)
Mark Wielaard a8d9e8
     return -1;
Mark Wielaard a8d9e8
 
Mark Wielaard a8d9e8
-  *size = total;
Mark Wielaard a8d9e8
+  /* This is a subrange_type or enumeration_type and we've set COUNT.
Mark Wielaard a8d9e8
+     Now determine the stride for this array.  */
Mark Wielaard a8d9e8
+  Dwarf_Word stride = eltsize;
Mark Wielaard a8d9e8
+  if (INTUSE(dwarf_attr_integrate) (die, DW_AT_byte_stride,
Mark Wielaard a8d9e8
+                                    attr_mem) != NULL)
Mark Wielaard a8d9e8
+    {
Mark Wielaard a8d9e8
+      if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
Mark Wielaard a8d9e8
+        return -1;
Mark Wielaard a8d9e8
+    }
Mark Wielaard a8d9e8
+  else if (INTUSE(dwarf_attr_integrate) (die, DW_AT_bit_stride,
Mark Wielaard a8d9e8
+                                         attr_mem) != NULL)
Mark Wielaard a8d9e8
+    {
Mark Wielaard a8d9e8
+      if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
Mark Wielaard a8d9e8
+        return -1;
Mark Wielaard a8d9e8
+      if (stride % 8) 	/* XXX maybe compute in bits? */
Mark Wielaard a8d9e8
+        return -1;
Mark Wielaard a8d9e8
+      stride /= 8;
Mark Wielaard a8d9e8
+    }
Mark Wielaard a8d9e8
+
Mark Wielaard a8d9e8
+  *size = count_total * stride;
Mark Wielaard a8d9e8
   return 0;
Mark Wielaard a8d9e8
 }
Mark Wielaard a8d9e8
 
Mark Wielaard a8d9e8
diff --git a/tests/run-aggregate-size.sh b/tests/run-aggregate-size.sh
Mark Wielaard a8d9e8
index 42b0742..6d8aa24 100755
Mark Wielaard a8d9e8
--- a/tests/run-aggregate-size.sh
Mark Wielaard a8d9e8
+++ b/tests/run-aggregate-size.sh
Mark Wielaard a8d9e8
@@ -54,6 +54,7 @@
Mark Wielaard a8d9e8
 # volatile int ia[32];
Mark Wielaard a8d9e8
 # const volatile void * const volatile restrict va[64];
Mark Wielaard a8d9e8
 # struct s sa[8];
Mark Wielaard a8d9e8
+# double d3d[3][4][5];
Mark Wielaard a8d9e8
 #
Mark Wielaard a8d9e8
 # typedef const int foo;
Mark Wielaard a8d9e8
 # typedef volatile foo bar;
Mark Wielaard a8d9e8
@@ -98,6 +99,7 @@ ca size 16
Mark Wielaard a8d9e8
 ia size 128
Mark Wielaard a8d9e8
 va size 512
Mark Wielaard a8d9e8
 sa size 128
Mark Wielaard a8d9e8
+d3d size 480
Mark Wielaard a8d9e8
 f size 4
Mark Wielaard a8d9e8
 b size 4
Mark Wielaard a8d9e8
 EOF
Mark Wielaard a8d9e8
diff --git a/tests/run-peel-type.sh b/tests/run-peel-type.sh
Mark Wielaard a8d9e8
index 7fd96e8..668e316 100755
Mark Wielaard a8d9e8
--- a/tests/run-peel-type.sh
Mark Wielaard a8d9e8
+++ b/tests/run-peel-type.sh
Mark Wielaard a8d9e8
@@ -55,6 +55,7 @@ ca raw type array_type
Mark Wielaard a8d9e8
 ia raw type array_type
Mark Wielaard a8d9e8
 va raw type array_type
Mark Wielaard a8d9e8
 sa raw type array_type
Mark Wielaard a8d9e8
+d3d raw type array_type
Mark Wielaard a8d9e8
 f raw type base_type
Mark Wielaard a8d9e8
 b raw type base_type
Mark Wielaard a8d9e8
 EOF
Mark Wielaard a8d9e8
Mark Wielaard a8d9e8
-- 
Mark Wielaard a8d9e8
1.8.3.1
Mark Wielaard a8d9e8
Mark Wielaard a8d9e8
From c25dc62e59dc42378370602b0d05415a42b051d6 Mon Sep 17 00:00:00 2001
Mark Wielaard a8d9e8
From: Mark Wielaard <mark@klomp.org>
Mark Wielaard a8d9e8
Date: Mon, 11 Dec 2017 23:58:34 +0100
Mark Wielaard a8d9e8
Subject: [PATCH 2/2] libdw: dwarf_aggregate_size should not peel the given
Mark Wielaard a8d9e8
 DIE.
Mark Wielaard a8d9e8
Mark Wielaard a8d9e8
Reserve memory for a new DIE first. The caller might not care, but it
Mark Wielaard a8d9e8
isn't really nice to change the DIE the caller gave us.
Mark Wielaard a8d9e8
Mark Wielaard a8d9e8
See also https://sourceware.org/bugzilla/show_bug.cgi?id=22546#c5
Mark Wielaard a8d9e8
Mark Wielaard a8d9e8
Signed-off-by: Mark Wielaard <mark@klomp.org>
Mark Wielaard a8d9e8
---
Mark Wielaard a8d9e8
 libdw/ChangeLog              | 5 +++++
Mark Wielaard a8d9e8
 libdw/dwarf_aggregate_size.c | 6 +++---
Mark Wielaard a8d9e8
 2 files changed, 8 insertions(+), 3 deletions(-)
Mark Wielaard a8d9e8
Mark Wielaard a8d9e8
diff --git a/libdw/dwarf_aggregate_size.c b/libdw/dwarf_aggregate_size.c
Mark Wielaard a8d9e8
index 3010c0a..6e50185 100644
Mark Wielaard a8d9e8
--- a/libdw/dwarf_aggregate_size.c
Mark Wielaard a8d9e8
+++ b/libdw/dwarf_aggregate_size.c
Mark Wielaard a8d9e8
@@ -199,12 +199,12 @@ aggregate_size (Dwarf_Die *die, Dwarf_Word *size, Dwarf_Die *type_mem)
Mark Wielaard a8d9e8
 int
Mark Wielaard a8d9e8
 dwarf_aggregate_size (Dwarf_Die *die, Dwarf_Word *size)
Mark Wielaard a8d9e8
 {
Mark Wielaard a8d9e8
-  Dwarf_Die type_mem;
Mark Wielaard a8d9e8
+  Dwarf_Die die_mem, type_mem;
Mark Wielaard a8d9e8
 
Mark Wielaard a8d9e8
-  if (INTUSE (dwarf_peel_type) (die, die) != 0)
Mark Wielaard a8d9e8
+  if (INTUSE (dwarf_peel_type) (die, &die_mem) != 0)
Mark Wielaard a8d9e8
     return -1;
Mark Wielaard a8d9e8
 
Mark Wielaard a8d9e8
-  return aggregate_size (die, size, &type_mem);
Mark Wielaard a8d9e8
+  return aggregate_size (&die_mem, size, &type_mem);
Mark Wielaard a8d9e8
 }
Mark Wielaard a8d9e8
 INTDEF (dwarf_aggregate_size)
Mark Wielaard a8d9e8
 OLD_VERSION (dwarf_aggregate_size, ELFUTILS_0.144)
Mark Wielaard a8d9e8
-- 
Mark Wielaard a8d9e8
1.8.3.1
Mark Wielaard a8d9e8