summaryrefslogtreecommitdiff
path: root/libdw
diff options
context:
space:
mode:
authorDima Kogan <dkogan@debian.org>2017-12-08 01:45:10 -0800
committerMark Wielaard <mark@klomp.org>2017-12-12 10:39:57 +0100
commita2246aaad96e062eb3bab55af9526aaa70adcfd0 (patch)
tree26738f3e7701d8be21c8a75bb320205d4dfbcc3d /libdw
parent57b7f381e167356fa47d58c18bbc2e856f75ee16 (diff)
downloadelfutils-a2246aaad96e062eb3bab55af9526aaa70adcfd0.tar.gz
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 <dima@secretsauce.net>
Diffstat (limited to 'libdw')
-rw-r--r--libdw/ChangeLog5
-rw-r--r--libdw/dwarf_aggregate_size.c43
2 files changed, 27 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 <dima@secretsauce.net>
+
+ * dwarf_aggregate_size.c (array_size): Handle multi-dimensional
+ arrays properly.
+
2017-11-03 Mark Wielaard <mark@klomp.org>
* 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;
}