From: Dima Kogan Date: Fri, 8 Dec 2017 09:45:10 +0000 (-0800) Subject: libdw: dwarf_aggregate_size() works with multi-dimensional arrays X-Git-Tag: elfutils-0.171~96 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a2246aaad96e062eb3bab55af9526aaa70adcfd0;p=thirdparty%2Felfutils.git 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 --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 437524402..2a6d71180 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 838468dd9..3010c0aa2 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 fe6335944..e16a3d047 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 42b0742b1..6d8aa2401 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 7fd96e84b..668e31617 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 7fa6a8a52..863338269 100644 Binary files a/tests/testfile-sizes3.o.bz2 and b/tests/testfile-sizes3.o.bz2 differ