This fixes
https://sourceware.org/bugzilla/show_bug.cgi?id=22546
>From 5f65148409fa08613f21280c5aea026d8b78366f Mon Sep 17 00:00:00 2001
From: Dima Kogan
Date: Fri, 8 Dec 2017 01:45:10 -0800
Subject: [PATCH] libdw: dwarf_aggregate_size() works with multi-dimensional
arrays
If we have a multidimensional array of dimensions (a,b,c) the number of elements
should be a*b*c, but prior to this patch dwarf_aggregate_size() would report
a+b+c instead.
This patch fixes the bug and adds a test that demonstrates the bug (the test
fails without the functional part of this patch).
Fixes: https://sourceware.org/bugzilla/show_bug.cgi?id=22546
Signed-off-by: Dima Kogan
---
libdw/ChangeLog | 5 +
libdw/dwarf_aggregate_size.c | 43 ++-
tests/ChangeLog | 6 ++
tests/run-aggregate-size.sh | 2 ++
tests/run-peel-type.sh | 1 +
tests/testfile-sizes3.o.bz2 | Bin 1147 -> 1208 bytes
6 files changed, 36 insertions(+), 21 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 43752440..2a6d7118 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2017-12-11 Dima Kogan
+
+ * dwarf_aggregate_size.c (array_size): Handle multi-dimensional
+ arrays properly.
+
2017-11-03 Mark Wielaard
* dwarf_getlocation.c (__libdw_intern_expression): Handle
diff --git a/libdw/dwarf_aggregate_size.c b/libdw/dwarf_aggregate_size.c
index 838468dd..3010c0aa 100644
--- a/libdw/dwarf_aggregate_size.c
+++ b/libdw/dwarf_aggregate_size.c
@@ -63,7 +63,7 @@ array_size (Dwarf_Die *die, Dwarf_Word *size,
return -1;
bool any = false;
- Dwarf_Word total = 0;
+ Dwarf_Word count_total = 1;
do
{
Dwarf_Word count;
@@ -134,34 +134,35 @@ array_size (Dwarf_Die *die, Dwarf_Word *size,
continue;
}
- /* This is a subrange_type or enumeration_type and we've set COUNT.
- Now determine the stride for this array dimension. */
- Dwarf_Word stride = eltsize;
- if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_byte_stride,
- attr_mem) != NULL)
- {
- if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
- return -1;
- }
- else if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_bit_stride,
- attr_mem) != NULL)
- {
- if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
- return -1;
- if (stride % 8) /* XXX maybe compute in bits? */
- return -1;
- stride /= 8;
- }
+ count_total *= count;
any = true;
- total += stride * count;
}
while (INTUSE(dwarf_siblingof) (&child, &child) == 0);
if (!any)
return -1;
- *size = total;
+ /* This is a subrange_type or enumeration_type and we've set COUNT.
+ Now determine the stride for this array. */
+ Dwarf_Word stride = eltsize;
+ if (INTUSE(dwarf_attr_integrate) (die, DW_AT_byte_stride,
+attr_mem) != NULL)
+{
+ if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
+return -1;
+}
+ else if (INTUSE(dwarf_attr_integrate) (die, DW_AT_bit_stride,
+ attr_mem) != NULL)
+{
+ if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
+return -1;
+ if (stride % 8) /* XXX maybe compute in bits? */
+return -1;
+ stride /= 8;
+}
+
+ *size = count_total * stride;
return 0;
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index fe633594..e16a3d04 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2017-12-11 Dima Kogan
+
+* run-aggregate-size.sh: Added check for multi-dimensional arrays.
+* run-peel-type.sh: Likewise.
+* testfile-sizes3.o.bz2: Likewise.
+
2017-12-07 Mark Wielaard
* run-readelf-variant.sh: New test.
diff --git a/tests/run-aggregate-size.sh b/tests/run-aggregate-size.sh
index 42b0742b..6d8aa240 100755
--- a/tests/run-aggregate-size.sh
+++ b/tests/run-aggregate-size.sh
@@ -54,6 +54,7 @@
# volatile int ia[32];
# const volatile void * const volatile restrict va[64];
# struct s sa[8];
+# double d3d[3][4][5];
#
# typedef const int foo;
# typedef volatile foo bar;
@@ -98,6 +99,7 @@ ca size 16
ia size 128
va size 512
sa size 128
+d3d size 480
f size 4
b size 4
EOF
diff --git a/tests/run-peel-type.sh b/tests/run-peel-type.sh
index 7fd96e84..668e3161 100755
--- a/tests/run-peel-type.sh
+++ b/tests/run-peel-type.sh
@@ -55,6 +55,7 @@ ca raw type array_type
ia raw type array_type
va raw type array_type
sa raw type array_type
+d3d raw type array_type
f raw type base_type
b raw type base_type
EOF
diff --git a/tests/testfile-sizes3.o.bz2 b/tests/testfile-sizes3.o.bz2
index 7fa6a8a529676bc8324d383c8d11f86c66ef453c..863338269bab61fb385344c489d48d1466915b61 100644
GIT binary patch
literal 1208
zcmV;p1V{TqT4*^jL0KkKS#6BOfdB+#|L_0*|Nrmj|NqbJ$0`5s-*CW0grxvV07V4=
z#YuEo&;$O8fgmQKVWLd}XliXV4Jo|{$vjM$h||>3lRynJ4@5STKx7&K(@dIZ^*v4M
zO&SQACR0r@JyX%5c}+CX000Jn004FExt044!3GGxF2m=ggpFiZdd005a7
z34shC