mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-25 19:22:07 +00:00
70d34beb69
195 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Dodji Seketeli
|
cf233e4fc2 |
Some small speed optimizations
* include/abg-ir.h (var_decl::get_naked_type): Declare new member function. * src/abg-ir.cc (var_decl::get_naked_type): Define it. (equals): For the var_decl overload, avoid copying symbol smart pointers. Likewise for variable type smart pointers. (hash_type_or_decl): Avoid accessing canonical type smart pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
a6aa328731 |
Mist style cleanups
Various style cleanups and comment additions here and there. * include/abg-ir.h: Add missing comments. Space cleanups. Use shorter typedefs rather than long template instantiation names. Use string rather than the longer std::string. * src/abg-ir.cc: Space cleanups. Add missing comments. User shorter typedefs. * src/abg-reader.cc: Likewise. * src/abg-writer.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
cf8eba68c3 |
Implement string interning for Libabigail
This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
6668baaff4 |
Add missing inequality operators for ABI artifacts
Some ABI artifact declared in the internal representation don't have inequality operator (!=) declared. I thought relying on the != operator provided by std::rel_ops would be enough, but it's not. Sometimes, especially for smart pointers to ABI artifacts we do not want the != operator of shared_ptr to be picked by argument dependent lookup. Rather, we want the deep operator!= to be picked up. In certain cases, this was causing subtle spurious change comparison reports. This patch thus systematically declares (and defines) operator!= whenever operator== is declared. * include/abg-ir.h ({translation_unit, elf_symbol::version, context_rel, decl_base, type_base, type_decl, array_type_def::subrange_type, enum_type_def::enumerator, dm_context_rel, template_parameter}::operator!=): Declare. (operator==): Make the overload form translation_unit_sptr, scope_decl_sptr, class_decl::base_spec_sptr, class_decl::member_function_template_sptr, class_decl::member_class_template_sptr take const references. (operator!=): Declare an an overload for the non-member operator != of translation_unit_sptr, elf_symbol_sptr, type_or_decl_base_sptr, type_base_sptr, scope_decl_sptr, type_decl, qualified_type_def_sptr, pointer_type_def_sptr, reference_type_def_sptr, enum_type_decl_sptr, class_decl_sptr, class_decl::base_spec_sptr, class_decl::member_function_template_sptr, class_decl::member_class_template_sptr. * src/abg-ir.cc ({translation_unit, elf_symbol::version, context_rel, decl_base, type_base, type_decl, array_type_def::subrange_type, enum_type_def::enumerator, dm_context_rel, template_parameter}::operator!=): Define. (operator==): Make the overload for translation_unit_sptr, scope_decl_sptr, class_decl::base_spec_sptr, class_decl::member_function_template_sptr, class_decl::member_class_template_sptr take const references. (operator!=): Define an an overload for the non-member operator != of translation_unit_sptr, elf_symbol_sptr, type_or_decl_base_sptr, type_base_sptr, scope_decl_sptr, type_decl, qualified_type_def_sptr, pointer_type_def_sptr, reference_type_def_sptr, enum_type_decl_sptr, class_decl_sptr, class_decl::base_spec_sptr, class_decl::member_function_template_sptr, class_decl::member_class_template_sptr. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
1bb3461d1d |
Bug 19638 - DWARF reader fails to link clone function to its declaration
There are three mains issues that cause the reported problem. Let's look at them closely. Suppose there is a DIE of a member function Klass::clone_of_foo, which is a clone of the DIE of the function Klass_foo, which is the concrete instance of the DIE of the declaration of Klass::foo. When libabigail's DWARF reader sees the DIE for Klass::clone_of_foo, it fails to get the context of the declaration of Klass::clone_of_foo -- which is Klass::foo. So, in the model built by libabigail, the symbol of Klass::clone_of_foo never gets associated to Klass::foo. It thus looks like Klass::clone is never defined. It also looks like that symbol is unreferenced. From there, a number of bad things happen. This is the first root cause of the reported problem. I call it issue 1/. 2/ While looking at this, I noticed that libabigail uses the underlying symbol name of a given function as the linkage name of that function, rather than using the value of the DW_AT_linkage_name DWARF property. This usually works, until the the function has a symbol which has several aliases. In that case, depending on the symbol alias that is used, a given function can have different linkage names. This causes problems later at comparison time. This is issue 2/. 3/ I also noticed that in the libabigail model, even if type Klass does have all its member functions (including Klass::foo) defined in in a particular translation unit TU1 , the same Klass in another translation unit TU2 might not have that Klass::foo defined, just because that function is not used in TU2. So after type canonicalization, if the version of Klass that is kept is the one from TU2, we end up with a type Klass *NOT* having Klass::foo defined. Sometimes, it's just that one member function in the canonical type doesn't have any underlying symbol, whereas the same member function in another type of the same class of equivalence as the canonical type does have that an underlying symbol. This is issue 3/. To address issue 1/ the patch fixes build_ir_node_from_die, in the case where a DW_TAG_subprogram DIE is being handled. It fixes the case of finding the root interface of the clone of a function definition. The patch also fixes a bug in build_function_decl that prevents it to update the linkage name of a function, *if* that function already had one. This was preventing build_function_decl to adjust the linkage name of a function which is a clone of an original function which already had a non-empty linkage name. To address 2/ the patch makes function_decl::get_id return the linkage name of the function, *if* it exists (rather than primarily returning the ID of the underlying symbol). To address 3/ the patch implements the copying of member functions or underlying function symbols missing from the canonical type -- but otherwise present in the type that has just been canonicalized. * include/abg-ir.h (decl_base::set_linkage_name): Make this member function virtual. (class_decl::string_mem_fn_ptr_map_type): Define new member type. (class_decl::find_member_function): Declare new member function. (copy_member_function): Declare new function. Declare it as friend of class_decl. (method_decl::set_linkage_name): Declare an overload for this virtual function. * src/abg-dwarf-reader.cc (build_function_decl): Allow updating of linkage_name even if the linkage_name was already defined. (build_ir_node_from_die): In the case DW_TAG_subprogram, make the lookup of scope of the DIE work even if it has both an abstract origin and a specification (DW_AT_abstract_origin and DW_AT_specification). * src/abg-ir.cc (maybe_adjust_canonical_type): Define new function. (canonicalize): Use it. (function_decl::get_id): Return the linkage name first, if it exist. (class_decl::priv::mem_fns_map_): New data member. (class_decl::find_member_function): Define new member function. (class_decl::method_decl::set_linkage_name): Likewise. (class_decl::add_member_function): Update the new data member class_decl::priv::mem_fns_map_. (copy_member_function): Define new static function. * tests/data/test-abidiff/test-PR18791-report0.txt: Adjust. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
421aa4ab5f |
Fix style cleanups
* include/abg-ir.h (method_type::{method_type, set_class_type, get_type, set_type}): Use type_base_sptr and class_decl_sptr instead of the full non-typedefed name. (method_type):Do some cleanups in the definition of the convenience typedefs. * src/abg-ir.cc (method_type::{method_type, set_class_type, get_type, set_type}): Use type_base_sptr and class_decl_sptr instead of the full non-typedefed name. * src/abg-writer.cc (write_class_decl): Add a comment. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
2f88edd3b3 |
Fix synthesizing of pointer type
Libabigail fails to to synthesize a non-existing pointer type to an existing type. This makes abicompat fail in weak mode when trying to detect changes to a function type where the parameter is a pointer to a structure which changed. In the application, the function is invoked and a pointer to the structure is passed to it. It appears that the type of structure is defined in the debug info of the application, but not the pointer to that structure. So abicompat needs to synthesize that pointer to struct in order to synthesize the type of the function, and so, compare it to the type of the function coming from the library. It appears that synthesizing a pointer type (to an existing type) is not supported. Only synthesizing qualified type was supported. This patch adds support for that and thus fixes the abicompat test case that is attached. * include/abg-ir.h: Update copyright. * src/abg-ir.cc (synthesize_type_from_translation_unit): Support synthesizing pointer types. * tests/data/test-abicompat/libtest8-fn-changed-libapp-v0.so: New test input. * tests/data/test-abicompat/libtest8-fn-changed-libapp-v1.so: Likewise. * tests/data/test-abicompat/test8-fn-changed-app: Likewise. * tests/data/test-abicompat/test8-fn-changed-app.c: Likewise. * tests/data/test-abicompat/test8-fn-changed-libapp-v0.c: Likewise. * tests/data/test-abicompat/test8-fn-changed-libapp-v0.h: Likewise. * tests/data/test-abicompat/test8-fn-changed-libapp-v1.c: Likewise. * tests/data/test-abicompat/test8-fn-changed-libapp-v1.h: Likewise. * tests/data/test-abicompat/test8-fn-changed-report-0.txt: Likewise. * tests/data/Makefile.am: Add the new test input files to source distribution. * tests/test-abicompat.cc (in_out_specs): Add the new test inputs above to the test harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
11c89cad3e |
Pass parm of elf_symbol::add_alias by reference
* include/abg-ir.h (elf_symbol::add_alias): Pass parameter by reference. * src/abg-ir.cc (elf_symbol::add_alias): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
640b3a2f59 |
Bug 19141 - Libabigail doesn't support common ELF symbols
Libabigail's internal representation of elf symbols fails to account for common symbols in relocatable files. There can be several common symbols of the same name (defined in a section of SHN_COMMON kind). In that case, Libabigail wrongly considers these multiple instances of the same common symbol as being alias, and that breaks some basic assumptions about aliases. Oops. This patch adds support for the common symbols (and the fact that relocatable files can have several instances of the same common symbol) and amends the ELF reader to make it properly represent those. * include/abg-ir.h (elf_symbol::elf_symbol): Take a new flag to say if the symbol is common. (elf_symbol::{is_common_symbol, has_other_common_instances, get_next_common_instance, add_common_instance}): New member functions. * src/abg-ir.cc (elf_symbol::priv::{is_common_, next_common_instance_): New data members. (elf_symbol::priv::priv): Adjust. (elf_symbol::{elf_symbol, create}): Take a new flag to say if the symbol is common. (textually_equals): Adjust to account for symbol common-ness. (elf_symbol::{is_common_symbol, has_other_common_instances, get_next_common_instance, add_common_instance}): Define new member functions. (elf_symbol::add_alias): Drive-by fix; compare symbols using pointer value. Value comparison is not necessary. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab, lookup_symbol_from_symtab) (read_context::lookup_elf_symbol_from_index): Adjust the creation of the symbol to account for common-ness. (read_context::load_symbol_maps): Recognize instances of a given common symbol and represent them as such. Do not mistake this with symbol aliases. * src/abg-reader.cc (build_elf_symbol): Adjust the creation of the symbol to account for common-ness. * src/abg-writer.cc (write_elf_symbol): Adjust symbol serialization to account common-ness. * tests/data/test-types-stability/pr19141-get5d.o: Add new test binary input. * tests/data/test-types-stability/pr19142-topo.o: Likewise. * tests/data/Makefile.am: Add the new test inputs to source distribution. * tests/test-types-stability.cc (elf_paths): The the new test inputs into account. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
64375c64d3 |
Make enum values take 64 bits on all platforms
The is still some changes in the way values of enumerators are represented in 32 and 64 bits systems. This is because the type of enumerators is size_t which 32 bits on 32 bits systems and 64 bits on 64 bits systems. The problem is, the output of, abidw can thus be different on 32 and 64 bits, making some tests output be different on these platforms. This patch thus uses uint64_t to represent enumerator values on all platforms. * include/abg-ir.h: Include stdint.h for int64_t. (enumerator::enumerator): Take an int64_t value for the value of the enumerator. (enumerator::{s,g}et_value): Take/return an int64_t value. * src/abg-ir.cc (enum_type_decl::enumerator::priv): Store the value in an int64_t. (enumerator::priv::priv): Take a int64_t for the value. (enum_type_decl::enumerator::enumerator): Likewise. (enum_type_decl::enumerator::{s,g}et_value): Take/returnan int64_t value. * src/abg-dwarf-reader.cc (die_unsigned_constant_attribute): Take an uint64_t value. (die_signed_constant_attribute): Take an int64_t value. (die_location, die_size_in_bits, die_access_specifier) (die_virtuality, die_is_virtual, die_is_declared_inline) (build_translation_unit_and_add_to_ir, build_type_decl) (build_enum_type, build_pointer_type_def, build_array_type): Adjust. * src/abg-reader.cc (build_enum_type_decl): Adjust. * src/abg-writer.cc (write_enum_type_decl): Do not cast the result of enumerator::get_value() anymore, it's value is now a int64_t. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
d50882bf4f |
Make class_decl::base_spec class follow the pimpl pattern
* include/abg-ir.h (class_decl::base_spec::priv): Declare new private data type. (class_decl::base_spec::priv_): Declare new pimpl data member. (class_decl::base_spec::{base_class_, offset_in_bits_, is_virtual_}): Remove. (class_decl::base_spec::{get_base_class, get_is_virtual, get_offset_in_bits}): Make these member functions out of line. * src/abg-ir.cc (struct class_decl::base_spec::priv): New type. (class_decl::base_spec::{get_base_class, get_is_virtual, get_offset_in_bits}): Define these functions here. (class_decl::base_spec::base_spec): Adjust because now there is only one pimpl data member to initialize. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
b017143876 |
[PERF] Access naked pointers for canonical types and function types
Performance profiling has shown that accessing shared_ptr to canonical types and function type during type comparison was noticeable slowing down the process. This patch thus access naked pointers for canonical types and function types at these performance hot spots. The profiling took place while running abidw --abidiff on the r300_dri.so binary. * include/abg-ir.h (type_base::get_naked_canonical_type): Declare new accessor. (function_decl::get_naked_canonical_type): Likewise. (function_decl::set_type): Pass a reference to the shared_ptr. * src/abg-ir.cc (type_base::priv::naked_canonical_type): New data member. (type_base::priv::priv): Initialize it. (canonicalize): Set the naked canonicalize type when we set its shared pointer. (type_base::get_naked_canonical_type): Define new accessor. ({pointer_type_def,reference_type_def,function_type,class_decl}::operator==): Use naked canonical pointers rather than the slower shared_ptr to canonical pointers. (function_decl::priv::naked_type_): New data member. (function_decl::priv::priv): Initialize it. (function_decl::get_naked_type): Define new accessor. (function_decl::set_type): Pass a reference to the shared_ptr . (equals): In the overload for function_decl, use the faster naked pointers to the type of the function. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
c0de97846c |
[PERF] Turn some pimpl pointers into naked pointers
The private data pointers of libabigail IR types are usually managed using shared_ptr. But performance profiling has shown that de-referencing some of these private data shared_ptr can have a noticeable performance impact. This is because de-referencing shared_ptr involves some locking that show up on some performance profile. So, for decl_base, type_base, and function_decl, this patch replaces the private data shared pointers by naked pointers. This speeds up the access to private data members, especially during comparison of class pointer, reference and function types. And that has a noticeable impact when libabigail handles huge binaries with lots of functions an type, like r300_dri.so. * include/abg-ir.h ({decl_base, type_base, function_decl}::priv_) Make this a naked pointer to priv, rather than a shared_ptr<priv>. * src/abg-ir.cc (decl_base::~decl_base): Destroy the private data pointer, aka pimpl pointer. (type_base::~type_base): Likewise. (function_decl::~function_decl): Likewise. (class_decl::~class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
0ec2416837 |
Bug 19126 - abidw segv on a dwz compressed version of r300_dri.so
Suppose a declaration D (which locus is in a file F) is imported at an offset offset of O1 into a compilation unit C1 and at an offset O2 (using DW_TAG_imported_unit) into a compilation unit C2. When the DWARF reader creates the ABI artifact for D in O1, its location is encoded by a location manager that is handled by C1. At O2 (in C2) the ABI artifact for D (created at O1, in C1) is re-used. But then, to decode the location of D, the DWARF reader wrongly uses the location manager that is handled by C2. It should use the location manager of C1, because that is the one used to encode the location of D. It picks the wrong location manager because it picks the wrong translation unit for D. Right now, the translation unit for a given declaration is the "current" translation unit at the moment the DIE was being inspected. And that is wrong when imported type units kick in. 1/ More generally, each ABI artifact should be associated with its translation unit, which is the current translation unit when the artifact was created. As there is just one copy of D, its translation unit should always be the same. 2/ Also, the location should ensure that about the location manager used to encode it is the same one used to decode it, so that this kind of bug cannot arise. This patch fixes the issue by doing 1/ and 2/. The r300_dri.so test case on which is was failing is not added to the test suite because it's too big. It was taking more than 55 minutes to have complete abidw --abidiff complete on that binary, on my machine. So I am going to work on the performance side of things, I think. * include/abg-ir.h (class location_manager): Forward declare it before class location. (location::loc_manager_): New data member. (location::location): Take the location manager in one overload and initialize the new loc_managers_ in all the overloads. (location::get_location_manager): New getter. (location::expand): New member function. (location::*): Add API doc to all entry points. (location_manager::expand_location): Take a const location. (type_or_decl_base::set_corpus): Remove. (type_or_decl_base::{get,set}_translation): New accessors. (decl_base::{decl_base,get_location}): Take or return a reference on location. (scope_decl::scope_decl): Likewise. (type_decl::type_decl): Likewise. (namespace_decl::namespace_decl): Likewise. (qualified_type_def::qualified_type_def): Likewise. (pointer_type_def::pointer_type_def): Likewise. (reference_type_def::reference_type_def): Likewise. (array_type_def::subrange_type::{subrange_type, get_location}): Likewise. (enum_type_decl::enum_type_decl): Likewise. (typedef_decl::typedef_decl): Likewise. (var_decl::var_decl): Likewise. (function_decl::function_decl): Likewise. (function_decl::parameter::parameter): Likewise. (template_decl::template_decl): Likewise. (type_tparameter::type_tparameter): Likewise. (non_type_tparameter::non_type_tparameter): Likewise. (function_tdecl::function_tdecl): Likewise. (class_tdecl::class_tdecl): Likewise. (class_decl::class_decl): Likewise. (class_decl::method_decl::method_decl): Likewise. * src/abg-ir.cc (location::expand_location): Define new member function. (type_or_decl_base::priv::corpus_): Remove. (type_or_decl_base::priv::translation_unit_): New data member. (type_or_decl_base::priv::priv): Adjust. (type_or_decl_base::set_corpus): Remove. (type_or_decl_base::get_corpus): Adjust. (type_or_decl_base::{get,set}_translation_unit): New member functions. (decl_base::priv::priv): Take a reference to location. (decl_base::decl_base): Likewise. (decl_base::get_location): Return a reference to location. (location_manager::create_new_location): Adjust. (location_manager::expand_location): Take a reference to location. (translation_unit::get_global_scope()): Adjust. (translation_unit::bind_function_type_life_time): Likewise. (scope_decl::{add,insert}_member_decl): Adjust. (get_translation_unit): Likewise. (type_decl::type_decl): Take a reference to location. (namespace_decl::namespace_decl): Likewise. (qualified_type_def::qualified_type_def): Likewise. (pointer_type_def::pointer_type_def): Likewise. (reference_type_def::reference_type_def): Likewise. (array_type_def::subrange_type::priv::priv): Likewise. (array_type_def::subrange_type::{subrange_type, get_location}): Likewise. (enum_type_decl::enum_type_decl): Likewise. (typedef_decl::typedef_decl): Likewise. (var_decl::var_decl): Likewise. (function_decl::function_decl): Likewise. (function_decl::parameter::parameter): Likewise. (template_decl::template_decl): Likewise. (type_tparameter::type_tparameter): Likewise. (non_type_tparameter::non_type_tparameter): Likewise. (function_tdecl::function_tdecl): Likewise. (class_tdecl::class_tdecl): Likewise. (class_decl::class_decl): Likewise. (class_decl::method_decl::method_decl): Likewise. * src/abg-writer.cc (write_location): Take a reference to location and adjust. (write_array_type_def, write_function_decl, dump_decl_location): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
2eda63d0f2 |
Fix internal name for pointers, typedefs and arrays
Internal names (and pretty representation) of types are used for type canonicalization. These were not being correctly computed for pointers typedefs and arrays because we were forgetting sometimes to use internal names of the underlying types, especially because of caching issues. This patch addresses that. Note that I noticed this while comparing the two versions of libgromacs_d.so.0.0.0 involved in the comparison referenced by bug https://bugzilla.redhat.com/show_bug.cgi?id=1283906. But then that library is too big (and takes too much time) to be included as a non regression test :( * include/abg-ir.h (pointer_type_def::priv_): New data structure. The type is now pimpled. (typedef_decl::priv_): Likewise. * src/abg-ir.cc (struct pointer_type_def::priv): New struct. (pointer_type_def::pointer_type_def): Adjust. (pointer_type_def::get_pointed_to_type): Likewise. (pointer_type_def::get_qualified_name): Store temporary/internal names into different caches. (array_type_def::priv::{temp_internal_qualified_name_, internal_qualified_name_}): New data members. (get_type_representation): In the overload for array_type_def, take requests for internal names into account. (array_type_def::get_qualified_name): Take requests for internal names into account. Store temporary/internal names into different caches. (typedef_decl::priv): New struct. (typedef_decl::typedef_decl): Adjust. (typedef_decl::get_underlying_type): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
fa4b7c8069 |
Fix comparison in qualified_type_diff::has_changes
* src/abg-comparison.cc (qualified_type_diff::has_changes): Make this stupid and simple, now that we have (fast) canonical type based comparison. * include/abg-ir.h (qualified_type_diff::operator==): Add an overload for qualified_type_diff here. (operator==): Likewise. * src/abg-ir.cc (qualified_type_diff::operator==): Define it. (operator==): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
43c908ed15 |
Bug 19336 - Better handle redundantly qualified reference types
Sometimes we can see const references in DWARF. But then, a reference is always const, so that qualified reference is redundant. Furthermore, having that construct make its way into the internal representation can cause awkward diagnostics. The DWARF reader was thus eliding such redundant qualifiers in the function "maybe_strip_qualification". It was doing so by stripping the qualifier from the qualified type. So const reference, for instance, becomes a (non-qualified) reference. In that case, we are turning a qualified type into a non-qualified one. But as the accompanying problem report suggests, this can cause issues during the DWARF parsing. This is because a given Debug Information Entry (DIE) of qualified type kind can be referenced elsewhere, by another type. That other type expects that DIE to be a qualified type. And libabigail's DWARF reader code enforces that. So the internal representation of a type resulting from a qualified type DIE must be a qualified type itself. So the way the function "maybe_strip_qualification" was doing the redundancy elision was wrong. This patch fixes that by keeping the type qualified, but introducing a "no-op" qualifier. Actually, the IR already has that "no-op" qualifier: abigail::ir::qualified_type_def::CV_NONE. So now "maybe_strip_qualification" just turns the CV_CONST qualifier into a CV_NONE one when the former is redundant. Now that the libabigail type system actually *has* types qualified with this no-op qualifier, we need to handle things like printing the name of such qualified types. When we are printing the name of the type for internal reasons (i.e, for type canonicalization purposes) we need to make a difference between the name of a no-op qualified type and the name of the underlying type of the qualified type, otherwise, the canonicalizer wrongly considers the two types as being equal. But then when we are printing the name of the no-op qualified type for diagnostics reasons, then the name is the same as the name of its underlying unqualified type. * src/abg-dwarf-reader.cc (maybe_strip_qualification): Do not nuke the qualified type. Rather, just turn the redundant const qualifier into a no-op one. * src/abg-comparison.cc (compute_diff_for_types): Look through no-op qualified types. * include/abg-ir.h (decl_base::{peek,set}_temporary_qualified_name): Declare new accessors. * src/abg-ir.cc (decl_base::priv::temporary_qualified_name_): New data member. (decl_base::{peek,set}_temporary_qualified_name): Define new accessors. (qualified_type_def::priv::{temporary_internal_name_, internal_name}): New data members. (qualified_type_def::build_name): For a no-op qualified type, the internal name (which contains the 'none' qualifier) is different from the non-internal name. (qualified_type_def::get_qualified_name): Handle temporary names and non-temporary names in two different caches. Also handle internal and non-internal names in two different caches. This makes four different caches. (qualified_name_setter::do_update): Do not touch the non-internal, non-temporary qualified name cache if the qualified parent name is empty. * tools/abidw.cc (main): change --check-alternate-debug-info to make it *not* display the name/path to the alternate debug info, when it's found. Rather, only --check-alternate-debug-info-base-name keeps displaying the base name of the alternate debug info. * tests/data/test-alt-dwarf-file/test1-libgromacs-debug-dir/*: New test material. * tests/data/Makefile.am: Add the new test material to the build system. * tests/test-alt-dwarf-file.cc (in_out_specs): Take the new test input into account. * tests/data/test-read-dwarf/test1.abi: Adjust. * tests/data/test-read-dwarf/test7.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.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/test17-pr19027.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. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
86ec69a86d |
Read enum values in the size_t and write them in ssize_t
Make sure to read enum values in the widest possible integer (size_t) but write them (in abixml writer) using a signed type to ease comparison. This makes the runtestreaddwarf pass on 32 bit x86, because we were losing some precision reading enum values using a signed integer. * include/abg-ir.h (enum_type_def::enumerator::get_value): Return a size_t. * src/abg-ir.cc (enum_type_decl::enumerator::get_value): Likewise. * src/abg-dwarf-reader.cc (die_signed_constant_attribute): #if-out this static function that is not used anymore. (build_enum_type): Read the value of the enumerator using a size_t value. * src/abg-reader.cc (build_enum_type_decl): Read the enum value using a long long int. * src/abg-writer.cc (write_enum_type_decl): Write using a ssize_t. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
ba980025fb |
Bug 19173 - Abidiff doesn't detect symbol size change in library
It appears that libabigail does not represent the size of ELF symbols, so it doesn't detect when a symbol size changes without impacting the size of the type of said symbol, as described by debug info. It appears that Address Sanitizer as implemented by Clang does change the size of variable symbols when it instruments those variables. And of course, the size of type of said symbols (as described by debug information) remains unchanged. This patch makes Libabigail become aware of symbol sizes, especially for variables. Symbol sizes for functions are ignored for now, because a change in a function symbol size is not an ABI change. The patch makes libabigail detect and report symbol size changes for variables, but looking at the ELF information, independently from the debug information. The patch adjusts the existing tests and adds a new test using the binaries that were filed in the bug report. * include/abg-ir.h (elf_symbol::{elf_symbol, create}): Take a size parameter. (elf_symbol::{get,set}_size): New accessors. * src/abg-ir.cc (elf_symbol::priv::size_): New data member. (elf_symbol::priv::priv): Initialize it. (elf_symbol::{elf_symbol, create}) Take a size parameter. (textually_equals): Compare the size of variable symbols. (elf_symbol::{get, set}_size): New accessors. * src/abg-comparison.cc (maybe_report_diff_for_symbol): New static function. ({function_decl_diff,var_diff}::report): Use it. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab, lookup_symbol_from_symtab) (read_context::lookup_elf_symbol_from_index): Set the size of the elf symbols' internal representation. * src/abg-reader.cc (build_elf_symbol): Read the size attribute if present. * src/abg-writer.cc (write_elf_symbol): Write the size attribute for variable symbols, if it's not zero. * tests/data/test-diff-dwarf/test34-pr19173-libfoo.so: New test input binary. * tests/data/test-diff-dwarf/test34-pr19173-libfoo2.so: Likewise. * tests/data/test-diff-dwarf/test34-pr19173-libfoo-report-0.txt: New reference test output. * tests/data/Makefile.am: Add the new test input binaries to the build system. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test input above to the test harness. * tests/data/test-diff-dwarf/test9-report.txt: Adjust. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * tests/data/test-read-dwarf/test1.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.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/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test6.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
4adbafaa43 |
Pass a bunch of parameters by reference as they ought to be
* include/abg-ir.h (operator==): In the overload for elf_symbol_sptr, pass the parameters by reference. * src/abg-ir.cc (operator==): Do the same at definition site. * src/abg-comparison.cc (maybe_report_diff_for_member): Pass parameters by reference. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
089b3fc762 |
Support updating a class in the abixml reader
In DWARF, the same class declaration can be present several times but with different "views", that is, it can be present in a first translation unit, but without any member type; then in a subsequent translation unit, its member types are defined. In another, it'll be completely defined, with all its data members and base classes. The DWARF reader knows how to amend the class to add new members to it, as they show up in the debug information. This patch adds the same functionality to the abixml reader. The writer has already started to write class declarations with different "views" too, since it's started to avoid duplicating full class definitions in every translation unit that uses them. Without this patch, abixml misses some class members, and that is a bug. * include/abg-ir.h (class_decl::{find_base_class, find_member_type, find_data_member}): Declare new member functions .. * src/abg-ir.cc (class_decl::{find_base_class, find_member_type, find_data_member}): ... and define them. * src/abg-reader.cc (build_class_decl): Add the ability to update a class to add new data members, member types and base classes to it, if necessary. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
093bc5da06 |
Pass some more parameters in reference
Profiling as shown that we might gain some precious cycles by passing some well chosen parameters by reference. * include/abg-ir.h (operator==): For the type_base_sptr and decl_base_sptr overloads, pass the parameters by reference. ({var,function}_decl::{set,get}_symbol): Pass the elf_symbol_ptr by reference. * src/abg-ir.cc (operator==): For the type_base_sptr and decl_base_sptr overloads, pass the parameters by reference, now in the definition. ({var,function}_decl::{set,get}_symbol): Pass the elf_symbol_ptr by reference, now in the definition. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
7bb65377a5 |
Accelerate a slow path in hash_type_or_decl()
Profiling shows that hash_type_or_decl() is very slow when hashing function parameters and base class specifications. This is because in those two cases we use the slow recursive hashing algorithm to hash types, rather than using the faster one based on using the pointer values of canonical types when possible. This was making corpora comparison very slow, as it uses hash_type_or_decl() to hash diffs of ABI artifacts. This patch fixes that. * include/abg-ir.h (is_function_parameter, is_class_base_spec): Declare new functions. * src/abg-ir.cc (is_function_parameter, is_class_base_spec): Define them. (hash_type_or_decl): Handle hashing of function parameters are class base specifications with the fast path of type hashing. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
60425d2996 |
Implement fast type lookup in a corpus
Profiling has shown that on libraries with a lot of class types declarations (more than 10K types), the phase of resolving those declarations to their definition was a hot spot. The lookup of the type definition inside the entire corpus was the bottleneck. This patch removes (or loosen) that bottleneck by doing away with the graph-walking-based type lookup algorithm that was used. Rather, maps of name -> types are maintained by each scope, in each translation unit. Those maps are updated each time a type is added to a scope. And looking up a type amounts to a lookup in a map. Way faster. * include/abg-fwd.h (components_to_type_name): Declare new function. * include/abg-ir.h (string_type_base_wptr_map_type): New typedef. (translation_unit::{get,set}_types): Declare new member functions. * src/abg-ir.cc (translation_unit::priv::types_): New data member. (translation_unit::{get,set}_types): Define these member functions. (maybe_update_types_lookup_map): Define new static function. (components_to_type_name): Define new function. (scope_decl::{add_member_decl, insert_member_decl}): Call the new maybe_update_types_lookup_map. (scope_decl::find_iterator_for_member): Fix logic. (class_decl::set_is_declaration_only): When a class declaration becomes a definition, update the name -> type map maintained in the scope of the class. (lookup_type_in_translation_unit): Use the hash map of qualified name -> types that is now maintained in the translation unit. This is way faster than the previous walking algorithm. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir): When fixing up global variable declarations that need to be re-added to the translation unit, use the new fast type lookup function. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
4b754229d1 |
Make canonicalization non sensitive to struct-ness of subtypes
In a previous patch, we made canonicalization independant from
struct-ness of class types. This was in this commit:
|
||
Dodji Seketeli
|
f1c48fe80f |
Handle aliased function decls when comparing decls in general
When comparing two declarations, we look at their linkage name. When the linkage names are different, then we infer that the two decls are different. But then, for *function* decls, it can happen that two different linkage names are actually for different symbols that do alias; the (ELF) symbols are different but they have the same address; so they point to the same "thing". The two functions are not different, then. And we were not supporting this last case of diffent linkage names that are aliases of each other. This patch adds support for that. * include/abg-ir.h (is_function_decl): Add a const to the reference parameter, making it comply with the definition. * src/abg-ir.cc (equals): In the overload for decl_base, when the two linkage names are different, consider the case of the decls being aliased functions. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
0e3416e7e2 |
Bug 19023 - Type canonicalization is sensitive to struct-ness
In some debug info of some shared library, the same type can be present as a struct in some translation units, and as a class in others. As we are using the "pretty representation" of types to hash types during type canonicalization, a "class foo" and "struct foo" are (wrongly) considered different, because those pretty representations are different. This patch changes the canonicalization code to make it independent from the struct-ness of the class being canonicalized. * include/abg-ir.h (class_decl::is_struct): Declare a setter for the "is-struct" property. * src/abg-ir.cc (class_decl::is_struct): And define that setter here. (type_base::get_canonical_type_for): Temporarily set the 'is-struct' flag of the class type to 'false' before building its pretty representation. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so: New test input binary. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: New test reference output. * tests/data/Makefile.am: Add the new test material above to the source distribution. * tests/test-read-dwarf.cc (in_out_specs): Add the two new test inputs to the list of test inputs to consider. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
9a0abd846b |
Use the ODR to speed up type canonicalization
This is the last patch of the series of 11 patches that started at the patch with the subject: constify is_class_type() And below starts the cover letter of this patch. While analyzing some libraries like libmozjs.so[1] it appeared that type canonicalization takes a significant time to comparing composite types that are re-defined in each translation units again and again. The One Definition Rule[2] says that two types with the same name shall designate the same thing; so when a type T being canonicalized has the same name of a canonical type C in the same ABI corpus, then this patch considers C as being the canonical type of T, without comparing T and C structurally. This saves us from comparing T and C. Before this patch, `abidw --noout libmozjs.so` was taking approximatively 5 minutes; with the patch, it takes 1 minutes and 30 seconds. To do this, the patch changes ABI artifacts to carry a pointer to the corpus it belongs to. Whenever an ABI artifact is added to a given context, the corpus of that context is propagated to the artifact; that is now possible as the artifact now carries the property of the corpus it belongs to. During type canonicalization the ODR-based optimization outlined above is performed as we can now compare the corpus of a given type again the one of another type; it's now possible to know if two types come from the same corpus. There are a few cases though were the optimization is not performed: - anonymous struct; when a struct is anonymous (it has no name, as described in the DWARF), the DWARF reader gives it a name nonetheless, so that diagnostics can refer to that anonymous type. But then all anonymous types in the system have the same name. So when faced with two anonymous types (with the same name) from the same corpus, it's wrong to consider that they name the same thing. The patch added an "is_anonymous" property to types created by the DWARF reader so that such anonymous types can be detected by the type canonicalizer; they are thus not involved in this optimization. Note that the abixml writer and reader have been updated to emit and read this property. - typedefs. I have seen in some boost code two typedefs of the same name refer to different underlying types. I believe this is a violation of ODR. I'll need to investigate on this later. And I think we really need to detect these ODR violations as part of this enhancement request: https://sourceware.org/bugzilla/show_bug.cgi?id=18941. - pointers, references, arrays and function types, as they can refer to the two exceptions above. This is the last patch of the series which aimed at speeding up type canonicalization in the context of types being re-defined a lot in translation units. [1]: Instruction to build libmozjs.so from the mongodb sources: - git clone https://github.com/mongodb/mongo.git - cd mongo - scons --link-model=dynamic build/opt/third_party/mozjs-38/libmozjs.so [2] One Definition Rule: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (class corpus): Forward-declare this. (is_anonymous_type): Declare this new function. * include/abg-ir.h (corpus_sptr, corpus_wptr): Declare these typedefs here too. (translation_unit::{g,s}et_corpus): Declare new member functions. (type_or_decl_base::{g,s}et_corpus): Likewise. * src/abg-ir.cc (translation_unit::priv::corpus): New data member. (translation_unit::priv::priv): Initialize it. (translation_unit::{g,s}et_corpus): Define new accessors. (translation_unit::get_global_scope): Propagate the corpus of the translation unit to its newly created global scope. (translation_unit::bind_function_type_life_time): Propagate the corpus of the translation_unit to the added function type. (type_or_decl_base::priv::corpus_): Add new data member. (type_or_decl_base::priv::priv): Initialize it. (type_or_decl_base::{g,s}et_corpus): Define new accessors. (scope_decl::{add,insert}_member_decl): Propagate the context's corpus to the member added to the context. (decl_base::priv::is_anonymous_): Add new data member. (decl_base::priv::priv): Initialize it. (decl_base::{s,g}et_is_anonymous): Define accessors. (is_anonymous_type): Define a new test function. (decl_base::set_name): Update the "is_anonymous" property. (type_base::get_canonical_type_for): Implement the ODR-based optimization to type canonicalization. * src/abg-corpus.cc (corpus::add): When a translation unit is added to a corpus, set the corpus of the translation unit. * src/abg-dwarf-reader.cc (build_enum_type) (build_class_type_and_add_to_ir): Set the "is_anonymous" flag on anonymous enums and classes. * src/abg-reader.cc (read_is_anonymous): Define new static function. (build_type_decl, build_enum_type, build_class_decl): Call the new read_is_anonymous function and set the "is_anonymous" property on the built type declaration. * src/abg-writer.cc (write_is_anonymous): Define new static function. (write_type_decl, write_enum_type_decl, write_class_decl): Write the "is_anonymous" property. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Adjust. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.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/test17-pr19027.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
38e17e0e07 |
Cleanup some IR type comparison operators
* include/abg-ir.h (operator==): In the overloads for type_decl, enum and class_decl, turn the shared_ptr parameter into a const reference to the shared_ptr. * src/abg-ir.cc (operator==): Do the same in the definitions. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
da4aaf467a |
Add missing deep equality operator for pointer and reference types
I noticed that abigail::ir::pointer_type_def_sptr and abigail::ir::reference_type_def_sptr did not have any free form operator '==' defined. So writing a == b with a and b being either pointer_type_def_sptr or reference_type_def_sptr was using pointer value comparison, as opposed to deeply comparing the pointer and reference instances. This patch adds those two missing operators. * include/abg-ir.h (pointer_type_def::operator==): Add an overload for pointer_type_def. (reference_type_def::operator==) Add an overload for reference_type_def. (operator==): Add an overload for pointer_type_def_sptr and reference_type_def_sptr. * src/abg-ir.cc (pointer_type_def::operator==): Make the overload for type_base& use the overload for decl_base&. Add a new overload for pointer_type_def& and make is use the overload for decl_base& too. (operator==): Add free form overloads for pointer_type_def& and reference_type_def&. (reference_type_def::operator==): Add comments. Add an overload for reference_type_def&. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Ondrej Oprala
|
9cb146a013 |
Bug 17340 - Support pointers and references to functions
* include/abg-comparison.h (compute_diff_for_distinct_kinds): Take the first two arguments of type const type_or_decl_base_sptr instead. * include/abg-ir.h (translation_unit::get_function_types): Declare new method. (function_types): Declare new typedef. * src/abg-comparison.cc (compute_diff_for_types): Take the first two arguments of type const type_or_decl_base_sptr instead of a const decl_base_sptr. (try_to_diff): Likewise. (try_to_diff<class_decl>): Likewise. (try_to_diff_distinct_kinds): Likewise. (compute_diff_for_distinct_kinds): Likewise. Also remove a variant accepting arguments of type const type_base_sptr. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Skip building a pointer if it points to the beginning of a vptr. (build_pointer_type_def): Declare utype_decl of type type_or_decl_base_sptr and adjust assignments to it accordingly. (build_function_type): New function definition. (build_function_decl): Call build_function_type instead of building an ftype manually. (build_ir_node_from_die): Amend case DW_TAG_subroutine_type with appropriate calls to build a function type. * src/abg-ir.cc (translation_unit::get_function_types): New method definition. ({pointer,reference}_type_def::pointer_type_def): Expect that pointed_to might not have an accompanying declaration and set a type's name in this case as well. ({pointer,reference}_type_def::get_qualified_name): Generate a qualified name even if the pointed-to type has no declaration. * src/abg-reader.cc (build_function_type): New function definition. (handle_element_node): Return a type_or_decl_base_sptr instead and try calling handle_function_type in addition to others. (handle_function_type): New function definition that calls build_function_type. (build_type): Try calling build_function_type as well. * src/abg-writer.cc (fn_shared_ptr_map): Declare new typedef. (write_context::{clear_referenced_fntypes_map,fntype_is_referenced, record_fntype_as_referenced}): New member functions. (write_translation_unit): Call the new clear_referenced_fntypes_map. * tests/data/Makefile.am: Add the new test material to the build system. (write_translation_unit): Separately write function types that have been recorded to emit by write_{pointer,reference}_type_def. (write_{pointer,reference}_type_def): Record the type pointed to as a type to be emitted if type == function type. (write_function_type): Write the details of a function type in the abixml format and unmark the type. * tests/data/test-diff-dwarf/test32-fnptr-changes-report-0.txt: New test reference report. * tests/data/test-diff-dwarf/test32-fnptr-changes-v{0,1}.cc: New test source files. * tests/data/test-diff-dwarf/test32-fnptr-changes-v{0,1}.o: New binary test inputs. * tests/data/test-diff-dwarf/test33-fnref-changes-report-0.txt: New test reference report. * tests/data/test-diff-dwarf/test33-fnref-changes-v{0,1}.cc: New test source files. * tests/data/test-diff-dwarf/test33-fnref-changes-v{0,1}.o: New binary test inputs. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.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/test9-pr18818-clang.so.abi: Likewise. * tests/data/test-read-write/test27.xml: New test source file. * tests/test-diff-dwarf.cc: Adjust to launch the new tests. * tests/test-read-write.cc: Likewise. Signed-off-by: Ondrej Oprala <ooprala@redhat.com> |
||
Ondrej Oprala
|
4ec793b9d0 |
Move a constructor declaration
* include/abg-ir.h (decl_base): Change the decl_base() declaration's visibility to private. Signed-off-by: Ondrej Oprala <ooprala@redhat.com> |
||
Dodji Seketeli
|
912eb7e36b |
Speed up type canonicalization by avoiding recursive hashing
Recursive type hashing was showing up as the major hot spot of performance profiles. After spending a few days on trying to speed it up, I have officially declared recursive tree node hashing as a slow process and I am giving up. I have thus decided to not use that at type canonicalization time. Rather, I am proposing a new type canonicalization routine where types are first hashed by hashing their pretty representation string. Basically, if T is the total number of types in the system and C the number of classes of equivalences (or the number of canonical types), the number of type comparisons done by a naive type canonicalization routine is N x C. With the worse C being equal to N itself, that worse number of comparisons is N*N. By using a hash table to store the canonical types, keyed by a hash of their pretty representation string, the number of type comparisons can be brought down to N*P, where P is a the greater number of which pretty representation string hash collide. That number P is usually small; my measurements show that N usually goes from 1 to 3. And moreover, computing the hash of the pretty representation string of the function is way faster than using the recursive type hash! As a result, running abidw on the libcilkrts.so library, from GCC goes from 12 minutes to 0.4 seconds! Incidentally, now that we are not trying to speed up the recursive type hashing process, all the complicated business we had around caching the result of the hashing is gone! I was thinking that hash cashing was inherently a bad idea, especially for recursive types -- that refer to themselves directly or indirectly, because in those case, depending on when you cached the hash value, the value of the hashing can be different. The abixml writer's code doesn't use the recursive type hash anymore either; it uses the pointer value of the canonical type as hash. Super fast too! The patch had to fix pieces here and there to comply with the fact that canonical types are now used across the board in a mandatory fashion. * include/abg-ir.h (canonical_types_map_type): Adjust this typedef to make it point to an unordered_map which the key is now a string and the value is a vector of types. (type_or_decl_base::{get_cached_hash_value, set_cached_hash_value, cached_hash}): Remove these member functions and type. (struct type_base::cached_hash): Remove. * src/abg-ir.cc (struct type_or_decl_base::priv::hash_): Remove. (type_or_decl_base::priv::priv): Adjust. (type_or_decl_base::{g,s}et_cached_hash_value): Remove. (type_base::get_canonical_type_for): For declaration-only classes, look at their definition for the canonical_type. Do not use recursive type hashing anymore. Rather, use the pretty representation string, and hash that. (class_decl::base_spec::get_hash): Do away with hash value caching here. (class_decl::operator==): For decl-only classes, look at their definitions for canonical types. (hash_type_or_decl): Adjust comment. Use the canonical type pointer value for type hash. That's the fast path. Otherwise, if not available, fall back to a slow path which is the recursive type hash we were using before. * src/abg-dwarf-reader.cc (maybe_canonicalize_type): Schedule all classes and typedef to classes for late canonicalization. * src/abg-hash.cc (type_base::dynamic_hash::operator()): There is no hash value cashing anymore. (type_base::cached_hash::operator()): Remove. * src/abg-reader.cc (read_context::get_type): Slight style adjustment. (read_translation_unit_from_file) (read_translation_unit_from_buffer): Do not forget to canonicalize types when reading just one translation unit. (build_type_tparameter, build_template_tparameter): Canonicalize the type. * src/abg-writer.cc (struct type_hasher): New hasher type. (type_ptr_map): Use a deep pointer comparison equal operator functor, and canonical types as type hash values. (write_class_decl): Do not write size and alignment on decl-only classes. Do not record decl-only classes as being emitted. Their definition must be emitted before. * tests/test-read-write.cc (main): Do not do abi testing on translation units (as opposed to doing it on abi corpora) as that code is not wet yet. We need to know how to diff namespaces. * tests/data/test-abidiff/test-PR18791-report0.txt: Adjust. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.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. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
3e146f14ba |
Update qualified name of a decl when it's added to its context
The building of the qualified name of a declaration is showing up in performance profile as a hot spot. This patch addresses that performance issue by updating the qualified name of a declaration whenever the declaration is added to its context and saving the result. Getting the qualified name later is just a matter of a string copy. I guess we can do something about those string copies later as they don't show up high performance profiles at the moment. * include/abg-ir.h (decl_base::priv_): Make this be public, so that the qualified name updater function can access it. (class class_decl): Make set_member_is_static() a friend function. * src/abg-ir.cc (class ::qualified_name_setter): New tree walking type. (decl_base::get_qualified_parent_name): Do not do any computation here. Just return the pre-computed qualified parent name string. (decl_base::get_qualified_name): Likewise, for qualified name. (scope_decl::{add,insert}_member_decl): Update the qualified name of the newly added member. Set the scope of the member here. It's not going to be set elsewhere, from now on. (add_decl_to_scope): Do not set the scope here anymore. Just call scope_decl::add_member_decl and let it do the work. (insert_decl_into_scope): Likewise, just call scope_decl::insert_member_decl and let it do the work. (class_decl::{add_data_member, add_member_function}): Do not handle details of context setting at this point. Let scope_decl::add_member_decl do it. Adjust the properties of the context relation afterwards. In add_data_member, when a data member changes its static-ness, move the data member into the class_decl::priv::non_static_data_members_ or out of it, as necessary. (class_decl::insert_member_decl): By default, a data member is considered static. (set_member_is_static): Move this definition after the definitions of class_decl, so that this function can see those. Also, when a data member changes its static-ness, move the data member into the class_decl::priv::non_static_data_members_ or out of it, as necessary. (class_decl::add_member_function_template): As we the underlying function template decl to the context, do not do any scope adding for it here. (::qualified_name_setter::{do_update, visit_begin}): Define new member functions. (update_qualified_name): Define new static function. * src/abg-reader.cc (build_class_decl): Make build_function_decl, build_var_decl, build_function_tdecl and build_class_tdecl automatically add the created decl to their context, and then update the properties of the resulting member decl later, just like what we do in the DWARF reader. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
b2e5366d3f |
Introduce the concept of environment
There are resources needed by the type system and other artifacts of libabigail. Today, when the life time of those resources need to be greater than all of artifacts of Abigail, then said resources are made global. But then global resources are not great, if anything because they complicate the future use of the library in concurrent computing setups. As I was in the need to add one resource to be used by the type system, I decided to sit down and first overhaul how these long lived resources needed to be handled. And here comes the concept of "environment". An environment is a place where one can put resources that need to live longer than all the other artifacts of the Abigail system. And so, the code that creates Abigail artifacts needs and environment of for said artifacts to use. In other words, artifacts now use an environment. This has interesting and strong implications. We can only compare two artifacts if they use the same environment. This is quite a strong requirement. But then when this requirement is fulfilled, comparing two types amounts to just comparing two pointer values; hash values for types can also be cached. Now *that* is great for speed of comparison, is it not? This patch introduce the concept environment (which is basically a new abigail::ir::environment type), removes the global variables and uses the environment instead. Each ABI artifact (either type or decl) now has a ::get_environment() member function to get its environment. This patch also disables the caching of hash values because the caching must happen only *after* all types have been canonicalized. We were not respecting that requirement until now, and that introduces wrong hash values. A subsequent patch is going to re-introduce hash value caching again, once the infrastructure is in place to set a flag in the environment (hah!) once type canonicalization is done, and then later read that flag when some client code requests a hash value, to know if we should look in the hash value cache or not. The patch obviously changes the output of numerous regression tests (if anything b/c it disables hash value caching) so 'make check' yields regressions. But then, it's only the subsequent patch that updates the tests. * include/abg-ir.h: Adjust note about memory management. (class environment): Declare new class. (translation_unit::translation_unit): Take an environment in parameter. (translation_unit::{g,s}et_environment): Declare new member functions. (type_or_decl_base::{g,s}et_environment): Likewise. (type_or_decl_base::{get_cached_hash_value, set_cached_hash_value}): Change the name of decl_base::peek_hash_value() and decl_base::set_hash() here into these and move them here. (type_or_decl_base::hashing_started): Move decl_base::hashing_started() here. ({g,s}et_environment_for_artifact): Declare new functions. (class decl_base): Move member functions hashing_started(), peek_hash_value() and set_hash() on to the type_or_decl_base base class. (scope_decl::scope_decl): Initialize the virtual member type_or_decl_base(). (type_decl::{get_void_type_decl, get_variadic_parameter_type_decl}): Remove these static member functions. They are now non-static member functions of the new environment type. * src/abg-ir.cc (class environment_setter): New internal class. (get_canonical_types_map): Remove. This now becomes a member function of the environment type. (class usage_watchdog): Remove. (usage_watchdog_{s,w}ptr): Remove these typedefs. (get_usage_watchdog_wptr, ref_usage_watchdog) (maybe_cleanup_type_system_data): Remove these functions. (translation_unit::priv::usage_watchdog_): Remove data member. (translation_unit::priv::env_): New data member. (translation_unit::priv::priv): Take an environment and initialize the new env_ data member. Do not initialize the removed usage_watchdog_. (translation_unit::translation_unit): Take an environment parameter. (translation_unit::get_global_scope): Set the environment of a new global scope. (translation_unit::{g,s}et_environment): New accessors. (translation_unit::bind_function_type_life_time): Set the environment of the function type. (struct environment::priv): New class. (environment::{environment, ~environment, get_canonical_types_map, get_variadic_parameter_type_decl, canonicalization_is_done}): New member functions. (struct type_or_decl_base::priv): New class. (type_or_decl_base::{type_or_decl_base, hashing_started, get_cached_hash_value, set_cached_hash_value, set_environment, get_environment, traverse}): New member functions. ({s,g}get_environment_for_artifact): New functions. (decl_base::priv::{hash_, hashing_started}): Remove. (decl_base::priv::priv): Adjust. (decl_base::decl_base): In the copy constructor, initialize the virtual base type_or_decl_base. Do not initialize hash_ and hashing_started data member that got removed. (decl_base::{hashing_started, peek_hash_value, set_hash}): Remove member functions. (strip_typedef): Set the environment of the new type which has its typedefs stripped off. Adjust the call to type_or_void(). (scope_decl::{add, insert}_member_decl): Set the environment of the new member decl to the environment of its scope. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Set the environment for the newly synthesized type. Adjust calls to type_or_void(). (type_or_void): Take an environment in parameter. Get the void type from the environment. (get_canonical_types_map): Remove. (type_base::get_canonical_type_for): Get the canonical types map from the environment, not from a global variable. (type_decl::{get_void_type_decl, get_variadic_parameter_type_decl}): Remove. (pointer_type_def::pointer_type_def): Adjust call to type_or_void. (reference_type_def::reference_type_def): Likewise. (function_decl::parameter::get_pretty_representation): Get the variadic parameter type decl from the environment. (class_decl::priv::classes_being_compared_): Remove static data member. (class_decl::priv::{mark_as_being_compared, unmark_as_being_compared, comparison_started): Use the "classes being compared" map from the environment. (class_decl::base_spec::get_hash): Adjust. (keep_type_alive): Get the alive types array from the environment) not from a global variable anymore. (get_next_string): Put the counter in thread-local storage. * src/abg-hash.cc (scope_decl:#️⃣:operator()) (function_decl:#️⃣:operator()): Do not handle caching (here). * include/abg-corpus.h (corpus::{g,s}et_environment): Declare new accessors. * src/abg-corpus.cc (corpus::priv::env): New data member. (corpus::priv::priv): Initialize it. (corpus::corpus): Take an environment in parameter. (corpus::{g,s}et_environment): Define new member functions (corpus::add): Set the environment of the newly added translation unit, if it's not set already set. In any case, assert that the translation unit must use the same environment as the corpus. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take an environment parameter. ({s,g}et_debug_info_root_path, {s,g}et_environment): Declare new functions. * src/abg-dwarf-reader.cc (read_context::{env_, offline_callbacks_}): New data members. (read_context::read_context): Initialize them. (read_context::clear_per_translation_unit_data): Do not touch the void type declaration, it doesn't belong to the translation unit. (read_context::{env, offline_callbacks}): New accessors. (read_context::{create_default_dwfl}): New member function. (read_context::dwfl_handle): Add a setter overload. ({s,g}et_debug_info_root_path): Define new accessors. (create_default_dwfl, create_dwfl_sptr, create_default_dwfl_sptr): Remove these. (build_translation_unit_and_add_to_ir): Adjust to pass the environment to the newly created translation unit. (build_function_decl): Adjust to pass the environment to the created function and parameter types. Get variadic parameter type node from the current environment, not from a global variable. And do not try to canonicalize function types here. (read_debug_info_into_corpus): Set the environment of the newly created corpus. (build_ir_node_for_void_type): Get the void type node from the current environment, rather than from a global variable. (create_read_context): Take the environment in parameter. Create the default dwarf front end library handle using the new member function of the read context. Set the current environment used by the reader. (read_corpus_from_elf): Take an environment in parameter. Overhaul. This is now simpler. (has_alt_debug_info): Adjust the call to create_read_context() to make it pass an empty environment. * include/abg-fwd.h (class environment): Forward declare. * include/abg-reader.h (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream) (read_corpus_from_native_xml): Take an environment in parameter. * src/abg-reader.cc (read_context::m_env): New data member. (read_context::read_context): Initialize it. (read_context::{get_environment, set_environment}): New data member. (read_translation_unit): Set environment of the new translation unit. (read_corpus_from_input): Set the environment of the new corpus. (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream, read_corpus_from_native_xml): Take an environment in parameter. (build_function_parameter): Get variadic parameter type from the environment. * src/abg-comparison.cc (compute_diff): Add asserts in all the overloads to ensure that the artifact being compared come from the same environment. * tests/print-diff-tree.cc (main): Create an env for the ABI artifacts to use. * tests/test-abidiff.cc (main): Likewise. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-ir-walker.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/test-read-write.cc (main): Likewise. * tools/abicompat.cc (main): Likewise. * tools/abidiff.cc (main): Likewise. * tools/abidw.cc (main): Likewise. * tools/abilint.cc (main): Likewise. * tools/abipkgdiff.cc (main): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
bb5085741b |
Fix redundant const qualifier stripping
In the DWARF reader, we strip the const qualifier when it applies to reference types because a reference is always const. Those redundant const qualifiers can later introduce spurious changes in type comparison. But then we were forgetting to add the stripped type to the IR, in some cases. This patch fixes that. * include/abg-ir.h (operator&, operator~): Add overloaded bitwise operators for qualified_type_def::CV. * src/abg-ir.cc (operator&, operator~): Define them. * src/abg-dwarf-reader.cc (maybe_strip_qualification): Fix comment. If there are multiple qualifiers, only strip the const one. (build_ir_node_from_die): Once we've built a qualified type, if the 'const' qualifier is stripped, then add the new (stripped) type to the set of new types. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
5822798dd1 |
Bug 18894 - Fix representation of enumerators in abixml format
It turns out that using a size_t to serialize an enumerator is not enough to represent things like enum foo {value = -3}; We need to represent it using ssize_t. Also, the patch avoids early canonicalization (when reading DWARF) of types that refer to themselves. This was leading to type degradation (serializing the type from IR to abixml and de-serializing it back to IR leads to a different type). * include/abg-ir.h (enum_type_decl::enumerator::get_value()): Change the type of this from size_t to ssize_t. * src/abg-ir.cc (enum_type_decl::enumerator::get_value): Do the same on the definition side. (non_canonicalized_subtype_detector::visit_begin): If a type refers to itself, late canonicalize it to have a similar hashing result as what the abixml reader does. * src/abg-reader.cc (build_enum_type_decl): Use ssize_t to read the value of enumerators. * tests/data/test-read-dwarf/test13-pr18894.so.abi: New test input. * tests/data/Makefile.am: Add the new test inputs above to source distribution. * tests/test-read-dwarf.cc (in_out_specs): Add new test inputs. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
425f8a4ec4 |
Detect vtable changes from member function changes
This patch adds vtable changes detection based on the detection of virtual member function changes. That is, when a member function changes, if that member function is virtual, then infer if the change implies changes to the vtable of the containing class. Before that patch, we were doing the vtable change detection when we were comparing two classes; we were then comparing their virtual member functions. But as for a given class all its virtual member functions are not necessarily emitted in the DWARF debug info (only the virtual member functions that are used in a given translation unit are emitted in that translation unit) it's not reliable to compare virtual member functions as part of comparing a given class. We thus decided some patches ago to stop comparing virtual member functions when we compare two classes. So with this patch now, we still detect changes to the vtable and emit an appropriate message to the user. * include/abg-ir.h (class_decl::{has_virtual_base, has_vtable}): Declare new member functions. * src/abg-comp-filter.cc (has_virtual_mem_fn_change): New overload for function_decl_diff. (has_virtual_mem_fn_change): In the overload for diff*, support virtual member function changes detection for function_decl_diff*. * src/abg-comparison.cc (function_decl_diff::report): Detect and report changes to a vtable by looking a changes that can happen to a given member function. (corpus_diff::report): Detect and report changes to vtables by looking at changes change to member functions. * tests/data/test-diff-dwarf/test29-vtable-changes-report-0.txt: New text input. * tests/data/test-diff-dwarf/test29-vtable-changes-v{0,1}.cc: Source code of new test input binaries. * tests/data/test-diff-dwarf/test29-vtable-changes-v{0,1}.o: New test input binaries. * tests/data/test-diff-dwarf/test30-vtable-changes-report-0.txt: New text input. * tests/data/test-diff-dwarf/test30-vtable-changes-v{0,1}.cc: New test input. * tests/data/test-diff-dwarf/test30-vtable-changes-v{0,1}.o: New test input binaries. * tests/data/test-diff-dwarf/test31-vtable-changes-report-0.txt: New test input. * tests/data/test-diff-dwarf/test31-vtable-changes-v{0,1}.cc: Source code of new test input binary. * tests/data/test-diff-dwarf/test31-vtable-changes-v{0,1}.o: New test input binary. * tests/data/Makefile.am: Add the new test input files above to source distribution. * tests/test-diff-dwarf.cc (in_out_specs): Consume the new test inputs above. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
fbba4bf0ed |
Fix template comparison operators
There are two issues in comparing templates currently. One is that comparing member class template recurses for ever (oops). The other is that the logic of comparing function templates is wrong and leads to false comparisons. * include/abg-ir.h (function_tdecl::operator==): Introduce a new virtual member operator that takes a function_tdecl&. * src/abg-ir.cc (class_decl::member_function_template::operator==): Avoid the static cast in the overload for member_base. In the overload for member_class_template, avoid infinite recursion. (function_tdecl::operator==): In the overload for decl_base, do not do the real work here in the overload for decl_base Rather, the real work is done in the new overload for function_tdecl, and all other overloads call that one. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
9ab2c3a3fd |
Use size/alignment of class definition when requested on declaration
Sometimes during hashing the "type sub-object" of a class can be queried for its size or alignment. In those case, if the class is a declaration that happens to be accompanied with a definition, its the size/alignment of the definition that we want, not the one of the declaration, that is zero. Otherwise, this can cause spurious hashing changes between two class types that are otherwise equivalent modulo the use of a class declaration. This patch being part of a series that aims at fixing a number of type hashing issues, the regression tests are adjusted at the end of the series, not here. * include/abg-ir.h (type_base::{set_size_in_bits, set_alignment_in_bits}): Make these member functions virtual. (class_decl::{set_size_in_bits, get_size_in_bits, get_alignment_in_bits, set_alignment_in_bits}): Declare these virtual member functions. * src/abg-ir.cc (class_decl::{set_size_in_bits, get_size_in_bits, get_alignment_in_bits, set_alignment_in_bits}): Define these virtual functions. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
39b2e8b7d5 |
Make decl_base::get_qualified_name() work when decl context changes
decl_base::get_qualified_name() caches its result. So when it's first called on a decl that is not added to a scope, what is returned is a non-qualified name. Which is all right. But then when the decl is later added to a scope, the cached result of decl_base::get_qualified_name() is not longer correct. This patch resets the cache of decl_base::get_qualified_name() when the decl gets added to a new scope. * include/abg-ir.h (class decl_base): Make class scope_decl a friend of decl_base. (type_base::priv_): Make this protected, rather than private. * src/abg-ir.cc (scope_decl::add_member_decl) (scope_decl::insert_member_decl): Reset the cache of the result of decl_base::get_qualified_name(). * tests/data/test-abidiff/test-PR18791-report0.txt: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
636202c833 |
Fix style issues
* include/abg-ir.h (struct ir_node_visitor): Fix the wording of the comment of this type. * src/abg-dwarf-reader.cc (build_ir_node_from_die): Fix the filling of the text of the comment of the code that chooses to perform early canonicalizing. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
0cf1828a90 |
Fix type synthesis to fix abicompat weak mode
While looking further in the issue Sinny Kumari reported, I realized that the weak mode wasn't working in that example either. It turned out that synthesizing qualified types was not working because we were just looking them up in the binary, rather than looking up the un-qualified underlying type and then synthezing the resulting qualified type. This patch just does that. * include/abg-fwd.h (synthesize_type_from_translation_unit): Declare new function. (synthesize_function_type_from_translation_unit): Make the translation_unit parameter non-const because the function needs to bind the life time of the synthesized function to the life time of the translation unit. Make this function be a friend of abigail::ir::translation_unit. (synthesize_function_type_from_translation_unit): * src/abg-ir.cc (translation_unit::priv::synthesized_types_): New data member. (synthesize_type_from_translation_unit): Define new function. (synthesize_function_type_from_translation_unit): Make the translation_unit parameter non-const. If the return is void, then take that in account carefuly. Rather than just looking up the type of parameters and return value, synthesize them too, especially when they are qualified types. Bind the life time of the synthesized function type to the lifetime of the translation unit. * tests/data/test-abicompat/test7-fn-changed-report-1.txt: New test reference output. * tests/test-abicompat.cc (in_out_spec): Run the harness on the exisiting test7-fn-changed-app and libtest7-fn-changed-libapp-v1 but in weak mode this time. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
7cae79e0d8 |
On changed fn, show symbol info when name is different from linkage name in C
In change reports for function sub-type changes, for the C language, when the name of the function is different from its linkage name, even when the function symbol has no aliases, show the symbol information of the function. * include/abg-ir.h (translation_unit::language): New enum type. (translation_unit::{get_language, set_language}): Declare new accessors. (translation_unit_language_to_string) (string_to_translation_unit_language, is_c_language) (is_cplus_plus_language): Declare new functions. * src/abg-ir.cc (translation_unit::priv::language_): New data member. (translation_unit::priv::language_): Initialize it. (translation_unit::{set_language, get_language}): Define new member functions. (translation_unit_language_to_string) (string_to_translation_unit_language, is_c_language) (is_cplus_plus_language): Define new functions. * src/abg-dwarf-reader.cc (dwarf_language_to_tu_language): New static function. (build_translation_unit_and_add_to_ir): Read the language of the translation unit. * src/abg-comparison.cc (corpus_diff::report): When reporting a change in a function sub-type, if we are in C language translation unit, if the function name is different from its linkage name, even if the symbol doesn't have any alias, show symbol information. * src/abg-reader.cc (read_translation_unit_from_input): Read the 'language' property of the translation unit, if present. * src/abg-writer.cc (write_translation_unit): Write the 'language' property to the translation unit, if present. * tests/data/test-read-dwarf/test0.abi: Adjust for the new 'language' property of the 'abi-instr' element. * tests/data/test-read-dwarf/test1.abi: Likewise. * tests/data/test-read-dwarf/test2.so.abi: Likewise. * tests/data/test-read-dwarf/test3.so.abi: Likewise. * tests/data/test-read-dwarf/test4.so.abi: Likewise. * tests/data/test-read-dwarf/test5.o.abi: Likewise. * tests/data/test-read-dwarf/test6.so.abi: Likewise. * tests/data/test-read-dwarf/test7.so.abi: Likewise. * tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
5b09ea77e2 |
Handle the life time of the map of canonical types
While working on something else, it turned out that we need to cleanup (de-allocate) the map of canonical types when all the translation units that own types are de-allocated. Otherwise, when new translation units are created later, the types in the canonical types map become unrelated to the types in these new translation units, leading to memory management issues. This patch introduces a "usage watchdog" which detects when no translation unit uses the type system anymore. That usage watchdog is then used in the destructor of the translation_unit type to de-allocate the global data that is logically owned by by the type system. The patch also changes the API to read translation units and corpora in a way that forces users to get a handle on the resulting shared pointer. * include/abg-ir.h (type_base::canonical_types_map_type): Move this typedef into abg-ir.cc and out of the type_base namespace. (type_base::get_canonical_types_map): Likewise. * src/abg-ir.cc (canonical_types_map_type): New typedef that got moved here from type_base::canonical_types_map_type. (get_canonical_types_map): Likewise got moved here from type_base::get_canonical_types_map. Made static in the process. (class usage_watchdog): New type. (usage_watchdog_sptr, usage_watchdog_wptr): New typedefs. (get_usage_watchdog, get_usage_watchdog_wptr, ref_usage_watchdog) (maybe_cleanup_type_system_data): New static functions. (translation_unit::priv::usage_watchdog_): Add new data member. (translation_unit::priv::priv): Get a reference on the usage watchdog. (translation_unit::priv::~priv): If the usage watchdog says that the type system is not used, then cleanup the global data logically owned by the type system. * include/abg-dwarf-reader.h (read_corpus_from_elf): Make this return a corpus and set the status by reference using a parameter. * src/abg-dwarf-reader.cc (read_corpus_from_elf): Implement the above. * include/abg-reader.h (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream): Remove the overloads that do not return a translation_unit_sptr and that pass it as a parameter. Only keep the overloads that return a translation_unit_sptr, forcing users of the API to own a proper reference on the resulting translation_unit pointer. That is important to handle the life time of the global data of the type system that need to be cleared when the last translation unit is de-allocated. * src/abg-reader.cc (read_translation_unit_from_input): Make this return a translation_unit_sptr. (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream): Remove the overloads that do not return a translation_unit_sptr and that pass it as a parameter. Only keep the overloads that return a translation_unit_sptr. (read_to_translation_unit): Make this return a translation_unit_sptr. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-ir-walker.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/test-read-write.cc (main): Likewise. * tools/abicompat.cc (main): Likewise. * tools/abidiff.cc (main): Likewise. * tools/abidw.cc (main): Likewise. * tools/abilint.cc (main): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
fe9fa7a05f |
Support filtering out just one alias of a function
Suppose a function private_foo() has a symbol private_foo and also a another one (an alias) named public_foo. Then suppose we want to filter out sub-type changes to private_foo(). But then we still want to see changes to public_foo. This patch does add this feature. The [suppress_function] directive now has a new (hidden) boolean 'allow_other_aliases' property. When set to 'yes' or 'true', if the function being looked at has an alias symbol that does *NOT* match the other properties of the directive, then the directive doesn't suppress reports for the function. This new property is set to yes by default. This means that when a function has got multiple aliases, to suppress the function, one needs to write a regular expression that matches the names of aliases. Otherwise the function will not be suppressed. * include/abg-comparison.h (function_suppression::{get, set}_allow_other_aliases): Declare new member functions. * src/abg-comparison.cc (function_suppression::priv::allow_other_aliases_): New data member. (function_suppression::priv::priv): Initialize it to 'true'. (function_suppression::{get, set}_allow_other_aliases): Define new member functions. (read_function_suppression): Parse the new "allow_other_aliases" property. (function_suppression::suppresses_function): Update to evaluate the new 'allow_other_aliases' property when there is a property to match against some a symbol name of the function. (corpus_diff::report): Fix the printing of function aliases when printing sub-type changes to properly emit the plural of the word 'symbol' when the function has several aliases. * include/abg-ir.h (elf_symbol::get_number_of_aliases): Declare new member function. * src/abg-ir.cc (elf_symbol::get_number_of_aliases): Define new member function. * doc/manuals/libabigail-concepts.rst: Update manual. * tests/data/test-diff-dwarf/test5-report.txt: Adjust. * tests/data/test-diff-suppr/libtest23-alias-filter-v0.so: New test input. * tests/data/test-diff-suppr/libtest23-alias-filter-v1.so: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-0.suppr: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-1.suppr: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-2.suppr: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-3.suppr: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-4.suppr: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-report-0.txt: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-report-1.txt: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-report-2.txt: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-report-3.txt: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-report-4.txt: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-report-5.txt: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-v0.c: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-v1.c: Likewise. * tests/data/test-diff-suppr/test23-alias-filter-version-script: Likewise. * tests/data/Makefile.am: Add the new test stuff to source distribution. * tests/test-diff-suppr.cc (in_out_spec): Add the tests inputs above to the list of input to run over. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
25dc383b40 |
Show aliases of functions with changed sub-types
The report emitted by abidiff now tells the user about the aliases of the current function, when that function has some sub-type changes. * include/abg-ir.h (elf_symbol::get_aliases_id_string): Declare new overload. * src/abg-ir.cc (elf_symbol::get_aliases_id_string): Define new overload. * src/abg-comparison.cc (corpus_diff::report): For functions with sub-type changes report their aliases. Do not do this if the function is a constructor or destructor because these almost always have aliases, at least with GCC and the developer most certainly has not done anything special for that; she would thus be uselessly surprised by that remote implementation detail. * tests/data/test-diff-dwarf/test5-report.txt: Adjust test. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
9e64891731 |
Do not compare static data members when comparing types
The comparison code was too eager in comparing class types because it
was comparing static data members in the process. This was causing
some spurious false positives about functions or variables sub-type
changes. This patch fixes that by not comparing static data members
when comparing class types.
* include/abg-ir.h (class_decl::get_non_static_data_members):
Declare new data members.
* src/abg-comparison.cc
(class_diff::ensure_lookup_tables_populated): Only look at
non-static data members.
(compute_diff): In the overload for class_decl, only compare
non-static data members.
* src/abg-hash.cc (class_decl:#️⃣:operator()): Do not hash
static data members members hashing a class_decl.
* src/abg-ir.cc (class_decl::priv::data_members_): New data
member.
(class_decl::priv::priv): When initializing data members, store
the non-static data members on the side, in the new
class_decl::priv::non_static_data_members_ data member.
(class_decl::get_non_static_data_members): Define member function.
(class_decl::add_data_member): Store the non-static data members
on the side in class_decl::priv::non_static_data_members_.
(equals): In the overload for class_decl, do not take in account
static data members when running the comparison.
* tests/data/test-diff-dwarf/test7-report.txt: Adjust.
* tests/data/test-diff-filter/test12-report.txt: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
|
||
Dodji Seketeli
|
723222568e |
Change the linkage name only when necessary
Up to now the linkage name of a declaration was set to the name of it's underlying symbol. This patch changes that to instead honour what the DW_AT_linkage_name DWARF property says, unless the value of that property is either missing or wrong. * include/abg-ir.h (elf_symbol::get_alias_from_name): Declare new member function. * src/abg-ir.cc (elf_symbol::get_alias_from_name): Define it. * src/abg-dwarf-reader.cc (build_var_decl, build_function_decl): Once the linkage name is supposed to contain the value of the DW_AT_linkage_name attribute, set it the name of the underlying symbol only if value of DW_At_linkage_name is missing or different from the names of all the aliases of the underlying symbol. * tests/data/test-read-dwarf/test2.so.abi: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
41d0ad035f |
Fix symbols comparison
While working on something else, I noticed that the code for handling copying symbols (and their aliases) was broken, and so comparing two symbols which main name were different by which had aliases that were equal was wrongly resulting in the two symbol being different. I think we shouldn't actually copy symbols and their aliases. Once a symbol is allocated, interested code should just manipulate that symbol by address rather than by value an thus do away with the copying. The patch does that, essentially. In the implementation of a symbol, the aliases as well as the main symbol are now weak pointers, rather than naked pointers. Numerous API entry points that were taking containers of elf_symbol (and were copying elf_symbols over) are not taking containers of smart pointers to elf_symbol. Copying of instances of elf_symbol is now thus disabled. As a result many tests that were exercising elf_symbols (with alias) comparison have been updated. As a result, many empty sub-result of PR libabigail/PR17948 are now fixed. * include/abg-ir.h (elf_symbol_wptr): New typedef. (elf_symbol): Make the constructors and assignment operator private. The type can neither be copied nor created with the new operator. (elf_symbol::create): New static member function. (elf_symbol::{get_main_symbol, get_next_alias, add_alias}): Adjust. ( compute_aliases_for_elf_symbol): Likewise. (elf_symbol::operator=): Make this private. (elf_symbol::get_alias_which_equals): Declare new member function. * src/abg-comp-filter.cc (function_name_changed_but_not_symbol): Adjust. * src/abg-comparison.cc (class_diff::ensure_lookup_tables_populated): Adjust. * src/abg-corpus.cc (corpus::priv::build_unreferenced_symbols_tables): Likewise. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Adjust. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab, lookup_symbol_from_elf_hash_tab) (lookup_symbol_from_symtab, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf): Adjust. (read_context::lookup_elf_symbol_from_index): Likewise. (read_context::lookup_elf_fn_symbol_from_address): Likewise. (read_context::lookup_elf_var_symbol_from_address): Likewise. (read_context::lookup_public_function_symbol_from_elf): Likewise. (read_context::lookup_public_variable_symbol_from_elf): Likewise. (read_context::load_symbol_maps): Likewise. (build_var_decl, build_function_decl): Likewise. * src/abg-ir.cc (elf_symbol::priv::{main_symbol_, next_alias_}): Change the type of these from elf_symbol* to elf_symbol_wptr. (elf_symbol::priv::priv): Adjust. (elf_symbol::{create, get_alias_which_equals}): Define new functions. (textually_equals): Likewise. (elf_symbol::{get_main_symbol, is_main_symbol, get_next_alias, add_alias}): Adjust to return or take elf_symbol_sptr type, rather than a elf_symbol* one. (elf_symbol::{get_aliases_id_string, does_alias}): Adjust. (compute_alias_for_elf_symbol): Likewise. (elf_symbol::operator==): Two symbols A and B are now equal if A has at least one alias that is textually equal to B. (equals): In the overload for function_decls, in the part where we compare the decl_base part of the functions without considering their decl names, we now also omit considering their linkage names, because we compared they symbols before. * tools/abisym.cc (main): Adjust. * tests/data/test-diff-dwarf/test12-report.txt: Adjust. * tests/data/test-diff-dwarf/test12-report.txt: Adjust. * tests/data/test-diff-dwarf/test18-alias-sym-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test8-report.txt: Adjust. * tests/data/test-diff-filter/test10-report.txt: Adjust. * tests/data/test-diff-filter/test13-report.txt: Adjust. * tests/data/test-diff-filter/test2-report.txt: Adjust. * tests/data/test-diff-filter/test20-inline-report-0.txt: Adjust. * tests/data/test-diff-filter/test20-inline-report-1.txt: Adjust. * tests/data/test-diff-filter/test9-report.txt: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |