mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-01 22:31:46 +00:00
ff91eea8cf
393 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
|
445923157d |
Update copyright notice
* include/abg-corpus.h: Update copyright notice. * include/abg-dwarf-reader.h: Likewise. * src/abg-comparison.cc: Likewise. * src/abg-corpus.cc: Likewise. * src/abg-ir.cc: Likewise. 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
|
e62901963f |
Bug 19658 - Type canonicalization slow for the 2nd binary loaded
When loading two binaries (e.g, when the library is used by abidiff), and when the second one does have deep types (e.g, classes with recursively deep hierarchies) with lots of duplicated types in lots of translation units, canonicalizing the types of the second binaries can take a *lot* of time, given the quadratic nature of the structural type comparisons that take place and the cheer number of those type comparisons (because of the duplication). There is already an optimization based on the One Definition Rule in the canonicalization code. That optimization avoids structural comparison of types of the same corpus which have the same name. But then, this optimization only works on types of the first corpus. As soon as we are loading a second corpus, all types being canonicalized are coming from a corpus that is different from the first corpus, by definition. So a structural comparison is taking place for *all* those types. The patch extends the existing optimization to make it work on the second corpus being loaded. Once a type from the second corpus is canonicalized, the canonical type is cached inside the corpus. Then, later, when a type with the same name has to be canonicalized, the system looks inside the cache of that corpus to see if there is a canonicalized type the same name. I tested the patch on this command: abipkgdiff --d1 nss-debuginfo-3.19.1-8.el6_7.i686.rpm \ --d2 nss-debuginfo-3.21.0-0.1.el6_7.i686.rpm \ nss-3.19.1-8.el6_7.i686.rpm \ nss-3.21.0-0.1.el6_7.i686.rpm I whitnessed a x10 speedup, at least. On binaries that don't have a lot of duplicated deep types, the patch doesn't have any noticeable effect. At lesat It doesn't slow things down in that case. * include/abg-corpus.h (corpus::{record_canonical_type, lookup_canonical_type}): Declare new member functions. * src/abg-corpus.cc (corpus::priv::canonical_types_): New data member. (corpus::{record_canonical_type, lookup_canonical_type}): Define new member functions. * src/abg-ir.cc (type_base::get_canonical_type_for): Cache the canonical type inside the corpus of the type being canonicalized. Then later when canonicalizing another type, lookup in the cache inside its corpus to see if there is a type with the same name. * tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
9cef1838c9 |
Add --verbose option to abidiff
This is useful to see the progress of e.g type canonicalization and visually spot where it takes times on some big binaries. To do this, this patch enables logging in libabigail itself too. * doc/manuals/abidiff.rst: Add documentation for new --verbose option. * include/abg-dwarf-reader.h (set_do_log): Declare new function. * src/abg-dwarf-reader.cc (read_context::do_log_): New data member. (read_context::read_context): Initialize the new data member. (read_context::do_log): Define accessors. (set_do_log): Define new function; (read_context::canonicalize_types_scheduled) (read_debug_info_into_corpus): Add logs. * tools/abidiff.cc (options::do_log): New data member. (options::options): Initialize it. (display_usage): Add an usage string for --verbose. (parse_command_line): Parse the new --verbose option. (main): Set the dwarf reader's context wrt presence of the --verbose option. 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
|
f8761a48af |
Add function lookup by linkage name to libabigail::corpus
Until now, it was not possible to lookup a function declaration from a corpus, using a symbol name for the function. This patch adds that functionnality, which is useful, at least for debugging purposes. * include/abg-corpus.h (corpus::lookup_functions): Declare new member function. * src/abg-corpus.cc (class corpus::exported_decls_builder::priv): Make class corpus be a friend of this type. (corpus::exported_decls_builder::priv::add_fn_to_id_fns_map): Fix a thinko that was preventing the fn_id -> functions map from ever being filled. Fix this function to make it associate each aliases of a given function to the function, in the hash table. (corpus::lookup_functions): Define new member function. 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
|
b0335a42d5 |
Prefix abidiff error message with the 'abidiff' program name
* include/abg-tools-utils.h (emit_prefix): Declare new function. (check_file): Add a new parameter with a default value, so that existing code keeps compiling. * src/abg-tools-utils.cc (emit_prefix): Define new function. (check_file): Use the emit_prefix function and give it the program name passed as a new parameter. * tools/abidiff.cc (display_usage, main): Use the new emit_prefix to prefix error messages. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
4b7e295b20 |
Bug 19596 - Incorrect exit status for incompatible ABI change
The comparison engine doesn't take virtual offset changes into account when deciding if a diff node carries an incompatible change. This is obviously an oversight. Fixed thus. * include/abg-comparison.h (enum diff_category): Adjust the comment for enumerator VIRTUAL_MEMBER_CHANGE_CATEGORY; changes of this category are incompatible ABI changes. (corpus_diff::diff_stats::num_func_with_virtual_offset_changes): Declare new accessors. * src/abg-comparison.cc (corpus_diff::diff_stats::priv::num_func_with_virt_offset_changes): New data member. (corpus_diff::diff_stats::priv::priv): Initialize the new data member. (corpus_diff::diff_stats::num_func_with_virtual_offset_changes): Define new accessors. (corpus_diff::priv::apply_filters_and_compute_diff_stats): Use the new accessor to set the number of functions with virtual offset changes onto the stats data structure. (corpus_diff::has_incompatible_changes): Take functions with virtual offset changes into account. * tests/test-abidiff-exit.cc: New test harness to test for exit codes of abidiff. * tests/Makefile.am: Build the new test harness runtestabidiff from the test-abidiff-exit.cc source file. * tests/data/test-abidiff-exit/test1-voffset-change-report0.txt: New reference test output. * tests/data/test-abidiff-exit/test1-voffset-change-v0.cc: New test input source code. * tests/data/test-abidiff-exit/test1-voffset-change-v0.o: New test input. * tests/data/test-abidiff-exit/test1-voffset-change-v1.cc: New test input source code. * tests/data/test-abidiff-exit/test1-voffset-change-v1.o: New test input. * tests/data/Makefile.am: tests/data/Makefile.am: Add the new test inputs above to the source distribution. 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
|
c3869ecc7b |
Bug 19434 - invalid character in attribute value
* include/abg-tools-utils.h (string_is_ascii_identifier): Declare new function. * src/abg-tools-utils.cc (string_is_ascii_identifier): Define new function. * src/abg-dwarf-reader.cc (build_function_type): Discard parameter name if it's made of non-identifier ascii characters. * tests/data/test-types-stability/pr19434-elf0: New test binary input file. * tests/data/Makefile.am: Add the new test input to source distribution. * tests/test-types-stability.cc: Test the new test input into account. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
f275939df2 |
Use worker threads pattern to speed up some tests
We are going to need to speed up more and more tests, and coding directly with libpthread for that can be tedious and bug-prone. So I devised an implementation for the worker threads design pattern instead, and used it to speed up some tests. * include/Makefile.am: Add the new abg-workers.h to source distribution. * include/abg-workers.h: New file. * src/Makefile.am: Add the new abg-worker.cc to source distribution. * src/abg-workers.cc: New file. * tests/test-utils.cc: Update copyright. Make get_src_dir() and get_build_dir() return a const char*, as opposed to returning a string. Make that const char reside in thread local storage, so that two concurrent threads can safely call these functions in parallel, without any race. * tests/test-utils.h: Make get_src_dir() and get_build_dir() return a const char*, as opposed to returning a string. * tests/test-abicompat.cc: Update copyright. Adjust for get_src_dir() and get_build_dir() change. * tests/test-abidiff.cc: Likewise. * tests/test-alt-dwarf-file.cc: Likewise. * tests/test-core-diff.cc: Likewise. * tests/test-diff-dwarf-abixml.cc: Likewise. * tests/test-diff-dwarf.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tests/test-lookup-syms.cc: Likewise. * tests/test-read-dwarf.cc: Likewise. * tests/test-read-write.cc: Likewise. * tests/test-types-stability.cc: Likewise. Use the new task queue type to run these tests in parallel. * tests/test-diff-filter.cc: Likewise. 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
|
5c8c049e70 |
Bug 19138 - Failure to relate variables address from DWARF and ELF
In this problem report libabigail's DWARF reader wrongly looks up the address of variables (that it got from DWARF) in the .bss section of the ELF file. But then, in these files (generated by the Intel C++ compiler) the variables we are looking at have their addresses in the .data1 section. This patch changes the DWARF/ELF reader to make it look for variable addresses in .data, .data1, .rodata and .bss sections, as it should be. * include/abg-dwarf-reader.h (elf_type::ELF_TYPE_RELOCATABLE): New enumerator. * src/abg-dwarf-reader.cc (find_section): Factorize this from ... (find_text_section, find_bss_section): ... these. (find_rodata_section, find_data_section, find_data1_section): Define new static functions. (elf_file_type): Move this static function definition up. (read_context::{get_elf_file_type, address_is_in_section, get_data_section_for_variable_address}): New member functions. (read_context::maybe_adjust_fn_sym_address): Adjust comment. Adjust to use the new read_context::get_data_section_for_variable_address(). * tests/data/test-types-stability/pr19138-elf0: New test input binary. * tests/data/Makefile.am: Add the new test input binary to the test suite. * tests/test-types-stability.cc (elf_paths): Take it into account. 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> |
||
Ondrej Oprala
|
6a7566d513 |
Add the option of printing the file, line and column information about a type being reported.
* bash-completion/abicompat: Complete the new "--no-show-locs" option. * bash-completion/abidiff: Likewise. * bash-completion/abidw: Likewise. * bash-completion/abipkgdiff: Likewise. * doc/manuals/abicompat.rst: Mention the new "--no-show-locs" option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-comparison.h (show_locs): Add declarations. * src/abg-comparison.cc: (diff_context::priv): Add a new switch called "show_locs_" and set its default value to false. (report_loc_info): New function. Outputting the extra information is conditionalized based on the associated diff contexts settings. (show_locs): define a getter/setter for diff_context::priv::show_locs_. ({distinct,pointer,reference,qualified_type,enum,class,scope,fn_parm, typedef,corpus}_diff::report): Call report_loc_info when appropriate. (maybe_report_diff_for_member): Likewise. (represent): Accept a const reference to a diff_context_sptr as a first argument and call report_loc_info on its second argument. * src/abg-dwarf-reader.cc: * tests/data/Makefile.am: Add the new test reference files. * tests/data/test-abicompat/test0-fn-changed-report-2.txt: New test reference output. * tests/data/test-abicompat/test5-fn-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test6-var-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test7-fn-changed-report-2.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-pkg/dirpkg-3-report-2.txt: Likewise. * tests/data/test-diff-suppr/test6-fn-suppr-report-0-1.txt: Likewise. * tests/test-abidiff.cc: Explicitly create a diff context and turn off location emitting. * tests/test-diff-dwarf.cc: Likewise. * tests/test-abicompat.cc: Add --no-show-locs to all existing test arguments. Run a few of the existing tests again, but without this option. * tests/test-diff-filter.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tools/abicompat.cc: Handle the new "--no-show-locs" option. * tools/abidiff.cc: Likewise. * tools/abidw.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Ondrej Oprala <ooprala@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
|
1466510881 |
[PERF] Pass a bunch of perf-sensitive smart pointers by reference
* include/abg-fwd.h (lookup_type_in_corpus, lookup_type_in_scope) (lookup_var_decl_in_scope): Pass the decls smart pointers by reference. * src/abg-ir.cc (lookup_type_in_corpus, lookup_type_in_scope) (lookup_var_decl_in_scope): Pass the decls smart pointers by reference, for performance reasons. 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
|
1bee40c075 |
Do not forget to peel qualified type off when peeling types
When peeling off typedefs, references and pointers to see if a type is made of a class type, we forget to peel qualified types off. This is in the context of parsing type info from DWARF and to determine if we should delay type canonicalization (because a given type is made of a class) or not. Fixed thus. * include/abg-fwd.h (peel_qualified_type): Declare new function ... * src/abg-ir.cc (peel_qualified_type): ... and define it. (peel_typedef_pointer_or_reference_type): Peel qualified types here too. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
35dd76bc69 |
Constify is_qualified_type()
* include/abg-fwd.h (is_qualified_type): Make this take a const parameter. * src/abg-ir.cc (is_qualified_type): 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
|
266fa9288e |
Add --version option to several libabigail tools
This patch changed the revision number of the libabigail library to make it reflect the fact that we are not in "release candidate" mode, before the first 1.0 release. So the revision number is now "rc0". The configuration manager has been updated to support version numbers that are strings, so that it can supports things like "rc0". Then, several libabigail tools have been modified to support the --version option to display their version number. * configure.ac: Set the version revision to "rc0". * doc/manuals/abicompat.rst: Adjust manual for new --version option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abilint.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-config.h (config::{m_format_minor, m_format_major}): Make these be strings. (config::{get,set}_format_minor_version_number): Make these return strings. (config::{get,set}_format_major_version_number): Make these return or take strings. (abigail_get_library_version): Make this take strings. * src/abg-config.cc (config::config): Adjust. (config::{get,set}_format_major_version_number): Make these return or take strings. (config::{get,set}_format_minor_version_number): Make these return strings. (abigail_get_library_version): Make this take strings. * include/abg-version.h.in: Make the version variables be strings. * src/abg-writer.cc (write_translation_unit): The version numbers are now strings so adjust. * tools/{abicompat,abidiff,abidw,abilint,abipkgdiff,abisym}.cc (options::display_version): New data member. (options::options): Initialize it. (display_usage): Add documentation for new --version option. (parse_command_line): Parse new --version option. (main): Support --version. 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
|
7b35e89315 |
Bug 19139 - DWARF reader doesn't handle garbage in function names
In this bug, the DWARF debug info of the binary (generated by Intel's ICC compiler) has interesting constructs like: [ 6b5a0] subprogram decl_line (data2) 787 decl_column (data1) 15 decl_file (data1) 46 declaration (flag) accessibility (data1) public (1) type (ref4) [ 6b56a] prototyped (flag) name (string) "ldiv" MIPS_linkage_name (string) "ldiv" [ 6b5b6] formal_parameter type (ref4) [ 5f2aa] name (string) "$Ë2" [ 6b5bf] formal_parameter type (ref4) [ 5f2aa] name (string) "$Ë3" Note the strings that make up the name of the formal parameters of the function, near the end: [ 6b5b6] formal_parameter type (ref4) [ 5f2aa] name (string) "$Ë2" [ 6b5bf] formal_parameter type (ref4) [ 5f2aa] name (string) "$Ë3" The strings "$Ë2" and $Ë3" (which are the names of the parameters of the function) are garbage. Libabigail's DWARF reader naively uses those strings as names for the function parameters, in the type of the function. Then, the abixml writer emits an XML document, with these strings as property values, representing the name of the type of the function. And of course, the XML later chokes when it tries to read that XML document, saying that the property is not valid UTF-8. This patch addresses the issue by dropping those garbage names on the floor, for function type names. In that context, any string that is not made of ASCII characters is considered as being garbage, for now. The patch, in the abixml writer, also escapes function parameters names so that they don't contain characters that are not allowed in XML. The abixml reader already handles the un-escaping of the names it reads, so I think there is nothing to do there. Ultimately, I guess I should get the unicode value of the characters of that string, encode the string into UTF-8 and use the result as the name for the parameter. That would mean using UTF-8 strings for function parameter names, and, for all declarations names. But that is too much for worfk too little gain for now. The great majority of the binaries we are dealing with are still using ASCII for declaration names. The patch also introduces a new test harness that runs "abidw --abidiff" on a bunch of input binaries. This harness runs over the binaries that were submitted in this bug report. * include/abg-tools-utils.h (string_is_ascii): Declare new function ... * src/abg-tools-utils.cc (string_is_ascii): ... and define it. * src/abg-writer.cc (write_function_type): Escape forbidden XML characters in function type names. * src/abg-dwarf-reader.cc (build_function_type): If a parameter name is not ascii, drop it on the floor. * tests/data/test-types-stability/pr19139-DomainNeighborMapInst.o: New test input binary. * tests/data/test-types-stability/pr19202-libmpi_gpfs.so.5.0: Likewise. * tests/data/Makefile.am: Add the new binaries above to the build system. * tests/test-types-stability.cc: New test harness. * tests/Makefile.am: Add the new test harness to the build system. 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
|
caaeaea10b |
Misc style cleanup
* include/abg-fwd.h: Remove unnecessary declaration of class parameter. * src/abg-ir.cc: Remove trailing space in a comment. * src/abg-reader.cc: Fix a comment. 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
|
1a6b957401 |
Fix const-ness of a function parameter
* include/abg-fwd.h (is_function_decl): Add a const to the parameter to make it comply with the definition in abg-ir.cc. Woops. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
f95af3a89a |
Do not compare access specs for member types & functions
It turns that in some DWARF (e.g, from the r300_dri.so binary in bug libabigail/19024) the same class Foo can be declared as a struct, and later defined as a class. Or the other way around. In some cases, Foo can be declared as a struct, have a member type Foo::Type with no access specifier, and later that member type is still present with no access specifier when Foo is defined as a class. So when comparing Foo::Type (from struct Foo) against Foo::Type (from class Foo) we must not consider the access specification of Type, otherwise, as in the first case it's 'public' and in the second case it's 'private', the two member types would be considered different. And something similar happens for member function declarations too. This patch thus avoids comparing access specifiers for member types and functions. Though it can be considered as a regression compared to what was being done before, access specifiers don't have an impact on ABI per se. And they can cause noise in the result, as we are seeing here. * include/abg-fwd.h (is_function_decl): Declare a new overload. * src/abg-ir.cc (is_function_decl): Define a new overload. (equals): In the overload for decl_base, do not compare access specifiers when comparing member functions and types. * tests/data/test-diff-dwarf/test0-report.txt: Adjust. * tests/data/test-diff-filter/test0-report.txt: Likewise. * tests/data/test-diff-filter/test01-report.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test4-report.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
e9bdb488b3 |
Bug 19025 - abixml writer forgets to emit some member types
When a member type (a type that is a member of a class) M is referenced by some types emitted by abixml, but the context of M (the class type which M is a member of) is not itself referenced by any ABI artifact, then abixml forgets to emit the context of M and thus M itself. With this patch, when the abixml writer has emitted almost all ABI artifacts for the current translation unit, it looks for types that have been referenced by the emitted ABI artifacts, but that haven't been emitted themselves. It then emits those referenced-but-not-emitted types, and makes sure their contexts are emitted as well. * include/abg-fwd.h (is_namespace): Fix prototype. * src/abg-writer.cc (struct type_ptr_comp_functor): New internal type. (sort_type_ptr_map): New static function. (write_context::m_referenced_types_map): Renamed m_referenced_fntypes_map data member into this. (write_context::get_referenced_types): New member function. (write_context::record_type_as_referenced): Renamed record_fntype_as_referenced member function into this. Adjust. (write_context::type_is_referenced): Renamed fntype_is_referenced into this. (write_context::clear_referenced_types_map): Renamed clear_referenced_fntypes_map member function into this. Adjust. (write_decl_in_scope): New static function. (write_translation_unit): Use it here to emit types that are referenced by other types in the TU, but that are not emitted. Adjust. (write_pointer_type_def, write_reference_type_def) (write_typedef_decl): Record the underlying types referenced by the emitted types as being, well, referenced. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so: New test binary input. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: New reference output of the binary input above. * tests/data/Makefile.am: Add the new test material above to the source distribution. * tests/test-read-dwarf.cc (in_out_spec): Add the 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/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. * 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. 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
|
48801d23e4 |
Bug 19037 - Make ABI corpus support several functions with same symbol
It turns out that, in DWARF, there can be function template instantiations foo<int>(int) and foo<TypedefOfInt>(TypedefOfInt) which have the same symbol name, if TypedefOfInt is a typedef of int. An ABI corpus retains only one function declaration per symbol name. So in the example of the bug the input DWARF has the two instantiations, but libabigail is just keeping one of the two; so the abixml only has one of the two template instantiations. This patch changes the ABI corpus model so that it represents the fact that there can be several function declarations for a given symbol. The patch then adjust the comparison engine to make it know about this new model. * include/abg-corpus.h (corpus::exported_decls_builder::str_{fn,var}_ptr_map_type): Remove these typedefs from here as they only used internally in abg-corpus.cc. So we move them there instead. * src/abg-corpus.cc (str_fn_ptrs_map_type): New typedef. (str_var_ptr_map_type): Moved the typedef that was in corpus::exported_decls_builder here. (corpus::exported_decls_builder::id_fns_map_): Rename the fns_ data member into this. Make it have a str_fn_ptrs_map_type as a type. (corpus::exported_decls_builder::id_fns_map): Renamed the fns_map() accessor into this one. (corpus::exported_decls_builder::{fn_id_is_in_id_fns_map, fn_is_in_fns}): New member functions. (corpus::exported_decls_builder::fn_is_in_id_fns_map): Rename fn_is_in_map into this. (corpus::exported_decls_builder::add_fn_to_id_fns_map): Rename add_fn_to_map into this. (corpus::exported_decls_builder::add_fn_to_exported): Adjust. (corpus::exported_decls_builder::maybe_add_fn_to_exported_fns): Adjust. * src/abg-comparison.cc (function_decl_diff::report): Emit reports about function name changes (for a given function ID) only if there are sub-type changes to be reported for the function. In that case, do not forget to emit the sub-type changes after the name changes have been reported. (corpus_diff::priv::ensure_lookup_tables_populated): Several functions of the same ID can be removed or added from/to the corpus. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so: New test input binary. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: New test output reference. * tests/data/Makefile.am: Add the new test materials to the source distribution. * tests/test-read-dwarf.cc (in_out_specs): Adjust to add the new test inputs above. 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
|
6e36a4381d |
Late canonicalize all types that reference classes when reading DWARF
Until now, the DWARF reader would late canonicalize typedefs to classes, as well as classes. That is not enough. Let's also late-canonicalize pointers, references and array of classes too. This is because classes that might not be finished yet might be referenced by those types, and so we want to wait until they are finished before we canonicalize them. * include/abg-fwd.h (peel_array_type): Declare new function. * src/abg-ir.cc (peel_array_type): Define it. (peel_typedef_pointer_or_reference_type): Peel arrays too, to get the type of its element. * src/abg-dwarf-reader.cc (maybe_canonicalize_type): If a pointer, reference, array or typedef references a class, then do late-canonicalize this type. 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> |