diff options
author | Dima Kogan <dkogan@debian.org> | 2017-12-08 01:45:10 -0800 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2017-12-12 10:39:57 +0100 |
commit | a2246aaad96e062eb3bab55af9526aaa70adcfd0 (patch) | |
tree | 26738f3e7701d8be21c8a75bb320205d4dfbcc3d /libdw | |
parent | 57b7f381e167356fa47d58c18bbc2e856f75ee16 (diff) | |
download | elfutils-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/ChangeLog | 5 | ||||
-rw-r--r-- | libdw/dwarf_aggregate_size.c | 43 |
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; } |