dwarf-reader,ir: Merge member fns of classes

When looking at something else, I realized that in DWARF, two classes
C and C' of the same name and coming from the same corpus might not
have the same member functions that are defined.  This is probably
because for a given translation unit, some compilers emit debug info
only for the member functions that are used somehow.

So, depending on which of C or C' is the canonical class in the end,
we will not necessarily have the same member functions emitted in
ABIXML.  That is annoying.  So there was a kludge in
maybe_adjust_canonical_type to ensure that the canonical type has all
the member functions of the types belonging to same class of
equivalence.

This patch adds a pass before type canonicalization in the DWARF
reader to ensure that all classes of the same name in a given corpus
have the same member functions.  The patch thus removes the now
unnecessary kludge from maybe_adjust_canonical_type and asserts the
impossibility of the member function discrepancy.

	* src/abg-dwarf-reader.cc (reader::{copy_missing_member_functions,
	contains_anonymous_class, merge_member_functions_of_classes,
	merge_member_functions_in_classes_of_same_names}): Define new
	member functions.
	(reader::read_debug_info_into_corpus): Call the reader::new
	merge_member_functions_in_classes_of_same_names.
	* src/abg-ir.cc (maybe_adjust_canonical_type): When looking at the
	canonical type C of a type T, if they both come from the same
	corpus, assert that C has all the member functions of T.  This
	because the DWARF reader now ensures that all types have the same
	name in a given corpus have the same member functions.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2024-03-27 00:43:15 +01:00
parent fb92e0a322
commit d26bd3d246
17 changed files with 55415 additions and 40506 deletions

View File

@ -2388,6 +2388,8 @@ public:
}
}
merge_member_functions_in_classes_of_same_names();
/// Now, look at the types that needs to be canonicalized after the
/// translation has been constructed (which is just now) and
/// canonicalize them.
@ -4596,6 +4598,133 @@ public:
fns_with_no_symbol.clear();
}
/// Copy missing member functions from a source @ref class_decl to a
/// destination one.
///
/// If a function is present on the source @ref class_decl and not
/// on the destination one, then it's copied from the source class
/// to the destination one.
void
copy_missing_member_functions(const class_decl_sptr& dest_class,
const class_decl_sptr& src_class)
{
for (auto method : src_class->get_member_functions())
if (!method->get_linkage_name().empty())
if (!dest_class->find_member_function(method->get_linkage_name()))
{
method_decl_sptr copied_method =
copy_member_function(dest_class, method);
ABG_ASSERT(copied_method);
schedule_type_for_late_canonicalization(copied_method->get_type());
}
}
/// Test if there is an interator in a given range that points to
/// an anonymous class.
///
/// @param begin the start of the iterator range to consider.
///
/// @param end the end of the iterator range to consider. This
/// points to after the range.
template <typename iterator_type>
bool
contains_anonymous_class(const iterator_type& begin,
const iterator_type& end)
{
for (auto i = begin; i < end; ++i)
{
type_base_sptr t(*i);
class_decl_sptr c = is_class_type(t);
if (c && c->get_is_anonymous())
return true;
}
return false;
}
/// Ensure that all classes of the same name have the same virtual
/// member functions. So copy the virtual member functions from a
/// class C that have them to another class C that doesn't.
///
/// @param begin an iterator to the first member of the set of
/// classes which to merge virtual member functions for.
///
/// @param end an iterator to the last member (one past the end
/// actually) of the set of classes which to merge virtual member
/// functions for.
template <typename iterator_type>
void
merge_member_functions_of_classes(const iterator_type& begin,
const iterator_type& end)
{
if (contains_anonymous_class(begin, end))
return;
for (auto i = begin; i < end; ++i)
{
type_base_sptr t(*i);
class_decl_sptr reference_class = is_class_type(t);
if (!reference_class)
continue;
string n1 = reference_class->get_pretty_representation(true, true);
string n2;
for (auto j = begin; j < end; ++j)
{
if (j == i)
continue;
type_base_sptr type(*j);
class_decl_sptr klass = is_class_type(type);
if (!klass)
continue;
n2 = klass->get_pretty_representation(true, true);
ABG_ASSERT(n1 == n2);
copy_missing_member_functions(reference_class, klass);
copy_missing_member_functions(klass, reference_class);
}
}
}
/// Ensure that all classes of the same name have the same virtual
/// member functions. So copy the virtual member functions from a
/// class C that have them to another class C that doesn't.
void
merge_member_functions_in_classes_of_same_names()
{
corpus_sptr abi = corpus();
if (!abi)
return;
istring_type_base_wptrs_map_type& class_types =
abi->get_types().class_types();
for (auto entry : class_types)
{
auto& classes = entry.second;
if (classes.size() > 1)
{
bool a_class_has_member_fns = false;
for (auto& c : classes)
{
type_base_sptr t(c);
if (class_decl_sptr klass = is_class_type(t))
if (!klass->get_member_functions().empty())
{
a_class_has_member_fns = true;
break;
}
}
if (a_class_has_member_fns)
merge_member_functions_of_classes(classes.begin(),
classes.end());
}
}
}
/// @return vectors of types created during the analysis of the
/// DWARF and in the need of being canonicalized.<<<<<<< HEAD
/// Return a reference to the vector containing the types created
/// during the binary analysis but that are not tied to a given
/// DWARF DIE.

View File

@ -15811,16 +15811,18 @@ maybe_adjust_canonical_type(const type_base_sptr& canonical,
m->set_symbol(s1);
}
else
if (canonical_class->get_corpus()
&& cl->get_corpus()
&& (cl->get_corpus() == canonical_class->get_corpus()))
// There is a member function defined and publicly
// exported in the other class, and the canonical
// class doesn't have that member function. Let's
// copy that member function to the canonical class
// then.
{
method_decl_sptr method =
copy_member_function (canonical_class, *i);
canonicalize(method->get_type());
}
// exported in the other class and the canonical
// class doesn't have that member function. This
// should not have happened! For instance, the
// DWARF reader does merge the member functions of
// classes having the same name so that all of them
// end-up having the same member functions. What's
// going on here?
ABG_ASSERT_NOT_REACHED;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1065,6 +1065,45 @@
<function-type size-in-bits='32' id='30a82da4'>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='f7c5ae1e' const='yes' id='3002cd03'>
<parameter type-id='32d2f295' is-artificial='yes'/>
<return type-id='157d4f95'/>
</function-type>
<function-type size-in-bits='32' method-class-id='65c10d3d' const='yes' id='4cc4f76b'>
<parameter type-id='a5f3e61a' is-artificial='yes'/>
<parameter type-id='1a1ddb91'/>
<return type-id='a5a046cd'/>
</function-type>
<function-type size-in-bits='32' method-class-id='65c10d3d' id='79583a0c'>
<parameter type-id='5a61729d' is-artificial='yes'/>
<parameter type-id='79927164'/>
<return type-id='a5a046cd'/>
</function-type>
<function-type size-in-bits='32' method-class-id='f7c5ae1e' id='facc63b9'>
<parameter type-id='c70198d4' is-artificial='yes'/>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='f7c5ae1e' id='58e4150d'>
<parameter type-id='c70198d4' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<parameter type-id='922df12b'/>
<parameter type-id='922df12b'/>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='f7c5ae1e' id='f09ea7db'>
<parameter type-id='c70198d4' is-artificial='yes'/>
<parameter type-id='63e171df' is-artificial='yes'/>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='65c10d3d' id='3cf3871e'>
<parameter type-id='5a61729d' is-artificial='yes'/>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='65c10d3d' id='30b6456c'>
<parameter type-id='5a61729d' is-artificial='yes'/>
<parameter type-id='63e171df' is-artificial='yes'/>
<return type-id='48b5725f'/>
</function-type>
</abi-instr>
<abi-instr address-size='32' path='frameworks/base/libs/storage/IObbActionListener.cpp' language='LANG_C_plus_plus_14'>
<array-type-def dimensions='1' type-id='801a266d' size-in-bits='608' id='19b37a54'>
@ -1529,6 +1568,24 @@
</class-decl>
<typedef-decl name='wctrans_t' type-id='eaa32e2f' filepath='bionic/libc/include/bits/wctype.h' line='60' column='1' id='183c72c4'/>
<typedef-decl name='FILE' type-id='8d7b2c1f' filepath='bionic/libc/include/stdio.h' line='59' column='1' id='aa12d1bb'/>
<function-type size-in-bits='32' method-class-id='f8f7e309' const='yes' id='ff801c86'>
<parameter type-id='6a9db9a0' is-artificial='yes'/>
<return type-id='c894953d'/>
</function-type>
<function-type size-in-bits='32' method-class-id='f8f7e309' const='yes' id='ef9ba467'>
<parameter type-id='6a9db9a0' is-artificial='yes'/>
<parameter type-id='1a1ddb91'/>
<return type-id='a5a046cd'/>
</function-type>
<function-type size-in-bits='32' method-class-id='f8f7e309' id='05ee5af0'>
<parameter type-id='f7891b51' is-artificial='yes'/>
<parameter type-id='79927164'/>
<return type-id='a5a046cd'/>
</function-type>
<function-type size-in-bits='32' method-class-id='f8f7e309' id='e4473514'>
<parameter type-id='f7891b51' is-artificial='yes'/>
<return type-id='48b5725f'/>
</function-type>
</abi-instr>
<abi-instr address-size='32' path='frameworks/base/libs/storage/ObbInfo.cpp' language='LANG_C_plus_plus_14'>
<qualified-type-def type-id='65c10d3d' const='yes' id='dda33994'/>
@ -12833,6 +12890,15 @@
<parameter type-id='24159e91' filepath='frameworks/base/native/android/obb.cpp' line='52' column='1'/>
<return type-id='3ff5601b'/>
</function-decl>
<function-type size-in-bits='32' method-class-id='c73fabea' const='yes' id='10d43f71'>
<parameter type-id='197d55e1' is-artificial='yes'/>
<return type-id='b59d7dce'/>
</function-type>
<function-type size-in-bits='32' method-class-id='c73fabea' id='ea5cd5f9'>
<parameter type-id='26924198' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<return type-id='48b5725f'/>
</function-type>
</abi-instr>
<abi-instr address-size='32' path='frameworks/base/native/android/sensor.cpp' language='LANG_C_plus_plus_14'>
<array-type-def dimensions='1' type-id='a6c45d85' size-in-bits='448' id='7722ba46'>
@ -13889,6 +13955,127 @@
<parameter type-id='eaa32e2f'/>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='4da81c6e'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<return type-id='c894953d'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='3a429a52'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<return type-id='c894953d'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='79e48c45'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<parameter type-id='22923b4c'/>
<return type-id='c894953d'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' const='yes' id='98de5d56'>
<parameter type-id='e4896a10' is-artificial='yes'/>
<return type-id='157d4f95'/>
</function-type>
<function-type size-in-bits='32' method-class-id='b4c0d64f' id='995590ca'>
<parameter type-id='36e31287' is-artificial='yes'/>
<parameter type-id='8f92235e'/>
<parameter type-id='6d925e80'/>
<parameter type-id='1a1ddb91'/>
<parameter type-id='8f92235e'/>
<return type-id='a5a046cd'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='ab79f659'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<return type-id='3ff5601b'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='3b5a5b1e'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<parameter type-id='763d7e1a'/>
<return type-id='3ff5601b'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='e9c7ea01'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<parameter type-id='157d4f95'/>
<return type-id='3ff5601b'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='2777f989'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<parameter type-id='157d4f95'/>
<parameter type-id='922df12b'/>
<return type-id='3ff5601b'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='6c2662ee'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<parameter type-id='4ab96a04'/>
<return type-id='3ff5601b'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='ff8fe339'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<parameter type-id='4ab96a04'/>
<parameter type-id='4ab96a04'/>
<return type-id='3ff5601b'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='4adb99e9'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<parameter type-id='922df12b'/>
<parameter type-id='157d4f95'/>
<parameter type-id='157d4f95'/>
<parameter type-id='922df12b'/>
<return type-id='3ff5601b'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='ab944528'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<parameter type-id='9aa04798'/>
<return type-id='3ff5601b'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='735b9074'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='7392516d'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<parameter type-id='157d4f95'/>
<parameter type-id='157d4f95'/>
<parameter type-id='990ef79d'/>
<parameter type-id='922df12b'/>
<parameter type-id='0c3db078'/>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='e38eb461'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='157d4f95'/>
<parameter type-id='4ab96a04'/>
<parameter type-id='990ef79d'/>
<parameter type-id='922df12b'/>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='70de3849'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='7743ab4a'/>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='b45faa62'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='5f8c324f'/>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='1c886047'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='4ab96a04'/>
<return type-id='48b5725f'/>
</function-type>
<function-type size-in-bits='32' method-class-id='bf075117' id='9954ec52'>
<parameter type-id='9cb9149f' is-artificial='yes'/>
<parameter type-id='63e171df' is-artificial='yes'/>
<return type-id='48b5725f'/>
</function-type>
</abi-instr>
<abi-instr address-size='32' path='frameworks/base/native/android/surface_control.cpp' language='LANG_C_plus_plus_14'>
<array-type-def dimensions='1' type-id='3860fb7b' size-in-bits='512' id='ce213b98'>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff