mirror of
git://sourceware.org/git/libabigail.git
synced 2025-01-31 22:01:40 +00:00
Support DW_AT_count DWARF attribute
Libabigail's DWARF reader does not support the DW_AT_count attribute used to specify the number of elements in an array subrange. Rather, it uses the DW_AT_lower_bound and DW_AT_upper_bound attributes that are emitted by GCC. Recent versions of Clang, on the other hand, use the DW_AT_count attribute. This patch adds support for the DW_AT_count attribute too. * src/abg-dwarf-reader.cc (get_default_array_lower_bound): Define new static function. (build_array_type): Support the DW_AT_count attribute. * tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-clang.so: New test binary input. * tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-clang2.so: Likewise. * tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-clang-report-0.txt: New test reference output. * tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-gcc.so: New test binary input. * tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-gcc2.so: New test binary input. * tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-gcc-report-0.txt: New test reference output. * tests/data/test-diff-dwarf/test35-pr19173-libfoo-long.c: Source code for the binaries above. * tests/data/Makefile.am: Add the new test material to the build system. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test inputs to the harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
ba980025fb
commit
5d24cf87d7
@ -144,6 +144,9 @@ maybe_canonicalize_type(Dwarf_Off die_offset,
|
||||
bool in_alt_di,
|
||||
read_context& ctxt);
|
||||
|
||||
static int
|
||||
get_default_array_lower_bound(translation_unit::language l);
|
||||
|
||||
/// Convert an elf symbol type (given by the ELF{32,64}_ST_TYPE
|
||||
/// macros) into an elf_symbol::type value.
|
||||
///
|
||||
@ -6092,6 +6095,64 @@ dwarf_language_to_tu_language(size_t l)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the default array lower bound value as defined by the DWARF
|
||||
/// specification, version 4, depending on the language of the
|
||||
/// translation unit.
|
||||
///
|
||||
/// @param l the language of the translation unit.
|
||||
///
|
||||
/// @return the default array lower bound value.
|
||||
static int
|
||||
get_default_array_lower_bound(translation_unit::language l)
|
||||
{
|
||||
int value = 0;
|
||||
switch (l)
|
||||
{
|
||||
case translation_unit::LANG_UNKNOWN:
|
||||
value = 0;
|
||||
break;
|
||||
case translation_unit::LANG_Cobol74:
|
||||
case translation_unit::LANG_Cobol85:
|
||||
value = 1;
|
||||
break;
|
||||
case translation_unit::LANG_C89:
|
||||
case translation_unit::LANG_C99:
|
||||
case translation_unit::LANG_C11:
|
||||
case translation_unit::LANG_C:
|
||||
case translation_unit::LANG_C_plus_plus_11:
|
||||
case translation_unit::LANG_C_plus_plus_14:
|
||||
case translation_unit::LANG_C_plus_plus:
|
||||
case translation_unit::LANG_ObjC:
|
||||
case translation_unit::LANG_ObjC_plus_plus:
|
||||
value = 0;
|
||||
break;
|
||||
case translation_unit::LANG_Fortran77:
|
||||
case translation_unit::LANG_Fortran90:
|
||||
case translation_unit::LANG_Fortran95:
|
||||
case translation_unit::LANG_Ada83:
|
||||
case translation_unit::LANG_Ada95:
|
||||
case translation_unit::LANG_Pascal83:
|
||||
case translation_unit::LANG_Modula2:
|
||||
value = 1;
|
||||
break;
|
||||
case translation_unit::LANG_Java:
|
||||
value = 0;
|
||||
break;
|
||||
case translation_unit::LANG_PL1:
|
||||
value = 1;
|
||||
break;
|
||||
case translation_unit::LANG_UPC:
|
||||
case translation_unit::LANG_D:
|
||||
case translation_unit::LANG_Python:
|
||||
case translation_unit::LANG_Go:
|
||||
case translation_unit::LANG_Mips_Assembler:
|
||||
value = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// Given a DW_TAG_compile_unit, build and return the corresponding
|
||||
/// abigail::translation_unit ir node. Note that this function
|
||||
/// recursively reads the children dies of the current DIE and
|
||||
@ -7265,7 +7326,11 @@ build_array_type(read_context& ctxt,
|
||||
|
||||
Dwarf_Die child;
|
||||
array_type_def::subranges_type subranges;
|
||||
size_t upper_bound, lower_bound = 0;
|
||||
translation_unit::language language =
|
||||
ctxt.current_translation_unit()->get_language();
|
||||
size_t upper_bound = 0;
|
||||
size_t lower_bound = get_default_array_lower_bound(language);
|
||||
size_t count = 0;
|
||||
|
||||
if (dwarf_child(die, &child) == 0)
|
||||
{
|
||||
@ -7274,15 +7339,48 @@ build_array_type(read_context& ctxt,
|
||||
int child_tag = dwarf_tag(&child);
|
||||
if (child_tag == DW_TAG_subrange_type)
|
||||
{
|
||||
// usually not specified for C/C++
|
||||
// The DWARF 4 specifications says, in [5.11 Subrange
|
||||
// Type Entries]:
|
||||
//
|
||||
// The subrange entry may have the attributes
|
||||
// DW_AT_lower_bound and DW_AT_upper_bound to
|
||||
// specify, respectively, the lower and upper bound
|
||||
// values of the subrange.
|
||||
//
|
||||
// So let's look for DW_AT_lower_bound first.
|
||||
die_unsigned_constant_attribute(&child,
|
||||
DW_AT_lower_bound,
|
||||
lower_bound);
|
||||
|
||||
// Then, DW_AT_upper_bound.
|
||||
if (!die_unsigned_constant_attribute(&child,
|
||||
DW_AT_upper_bound,
|
||||
upper_bound))
|
||||
return result;
|
||||
{
|
||||
// The DWARF 4 spec says, in [5.11 Subrange Type
|
||||
// Entries]:
|
||||
//
|
||||
// The DW_AT_upper_bound attribute may be replaced
|
||||
// by a DW_AT_count attribute, whose value
|
||||
// describes the number of elements in the
|
||||
// subrange rather than the value of the last
|
||||
// element."
|
||||
//
|
||||
// So, as DW_AT_upper_bound is not present in this
|
||||
// case, let's see if there is a DW_AT_count.
|
||||
if (!die_unsigned_constant_attribute(&child,
|
||||
DW_AT_count,
|
||||
count))
|
||||
// We have no information about the number of
|
||||
// elements of the array. Let's bail out then.
|
||||
return result;
|
||||
|
||||
// We can deduce the upper_bound from the
|
||||
// lower_bound and the number of elements of the
|
||||
// array:
|
||||
if (size_t u = lower_bound + count)
|
||||
upper_bound = u - 1;
|
||||
}
|
||||
|
||||
array_type_def::subrange_sptr s
|
||||
(new array_type_def::subrange_type(lower_bound,
|
||||
|
@ -249,6 +249,12 @@ test-diff-dwarf/test33-fnref-changes-v1.o \
|
||||
test-diff-dwarf/test34-pr19173-libfoo.so \
|
||||
test-diff-dwarf/test34-pr19173-libfoo2.so \
|
||||
test-diff-dwarf/test34-pr19173-libfoo-report-0.txt \
|
||||
test-diff-dwarf/test35-pr19173-libfoo-long-gcc.so \
|
||||
test-diff-dwarf/test35-pr19173-libfoo-long-gcc2.so \
|
||||
test-diff-dwarf/test35-pr19173-libfoo-long-gcc-report-0.txt \
|
||||
test-diff-dwarf/test35-pr19173-libfoo-long-clang.so \
|
||||
test-diff-dwarf/test35-pr19173-libfoo-long-clang2.so \
|
||||
test-diff-dwarf/test35-pr19173-libfoo-long-clang-report-0.txt \
|
||||
\
|
||||
test-read-dwarf/test0 \
|
||||
test-read-dwarf/test0.abi \
|
||||
|
@ -0,0 +1,13 @@
|
||||
Functions changes summary: 0 Removed, 0 Changed, 0 Added function
|
||||
Variables changes summary: 0 Removed, 1 Changed, 0 Added variable
|
||||
|
||||
1 Changed variable:
|
||||
|
||||
[C]'char buggy_symbol[5]' was changed to 'char buggy_symbol[10]':
|
||||
size of symbol (in bytes) changed from 5 to 10
|
||||
type of variable changed:
|
||||
type name changed from 'char[5]' to 'char[10]'
|
||||
array type size changed from 40 to 80 bits:
|
||||
array type subrange 1 changed length from 5 to 10
|
||||
|
||||
|
BIN
tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-clang.so
Executable file
BIN
tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-clang.so
Executable file
Binary file not shown.
BIN
tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-clang2.so
Executable file
BIN
tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-clang2.so
Executable file
Binary file not shown.
@ -0,0 +1,13 @@
|
||||
Functions changes summary: 0 Removed, 0 Changed, 0 Added function
|
||||
Variables changes summary: 0 Removed, 1 Changed, 0 Added variable
|
||||
|
||||
1 Changed variable:
|
||||
|
||||
[C]'char buggy_symbol[5]' was changed to 'char buggy_symbol[10]':
|
||||
size of symbol (in bytes) changed from 5 to 10
|
||||
type of variable changed:
|
||||
type name changed from 'char[5]' to 'char[10]'
|
||||
array type size changed from 40 to 80 bits:
|
||||
array type subrange 1 changed length from 5 to 10
|
||||
|
||||
|
BIN
tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-gcc.so
Executable file
BIN
tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-gcc.so
Executable file
Binary file not shown.
BIN
tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-gcc2.so
Executable file
BIN
tests/data/test-diff-dwarf/test35-pr19173-libfoo-long-gcc2.so
Executable file
Binary file not shown.
15
tests/data/test-diff-dwarf/test35-pr19173-libfoo-long.c
Normal file
15
tests/data/test-diff-dwarf/test35-pr19173-libfoo-long.c
Normal file
@ -0,0 +1,15 @@
|
||||
// This file is the source code for 4 binaries.
|
||||
// It comes from one of the comments of bug libabigail/19173.
|
||||
|
||||
// To compile the first two binaries, please do:
|
||||
// gcc test35-pr19173-libfoo-long.c -shared -fpic -o test35-pr19173-libfoo-long-gcc.so -g
|
||||
// gcc test35-pr19173-libfoo-long.c -shared -fpic -o test35-pr19173-libfoo-long-gcc2.so -g -DLONG
|
||||
//
|
||||
// To compile the next two binaries, please do:
|
||||
// clang test35-pr19173-libfoo-long.c -shared -fpic -o test35-pr19173-libfoo-long-clang.so -g
|
||||
// clang test35-pr19173-libfoo-long.c -shared -fpic -o test35-pr19173-libfoo-long-clang2.so -g -DLONG
|
||||
#ifdef LONG
|
||||
char buggy_symbol[10];
|
||||
#else
|
||||
char buggy_symbol[5];
|
||||
#endif
|
@ -272,6 +272,18 @@ InOutSpec in_out_specs[] =
|
||||
"data/test-diff-dwarf/test34-pr19173-libfoo-report-0.txt",
|
||||
"output/test-diff-dwarf/test34-pr19173-libfoo-report-0.txt"
|
||||
},
|
||||
{
|
||||
"data/test-diff-dwarf/test35-pr19173-libfoo-long-gcc.so",
|
||||
"data/test-diff-dwarf/test35-pr19173-libfoo-long-gcc2.so",
|
||||
"data/test-diff-dwarf/test35-pr19173-libfoo-long-gcc-report-0.txt",
|
||||
"output/test-diff-dwarf/test35-pr19173-libfoo-long-gcc-report-0.txt"
|
||||
},
|
||||
{
|
||||
"data/test-diff-dwarf/test35-pr19173-libfoo-long-clang.so",
|
||||
"data/test-diff-dwarf/test35-pr19173-libfoo-long-clang2.so",
|
||||
"data/test-diff-dwarf/test35-pr19173-libfoo-long-clang-report-0.txt",
|
||||
"output/test-diff-dwarf/test35-pr19173-libfoo-long-clang-report-0.txt"
|
||||
},
|
||||
// This should be the last entry
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user