libabigail/tests/data/test-read-dwarf/test2.so.abi

81 lines
5.8 KiB
Plaintext
Raw Normal View History

Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
<abi-corpus path='data/test-read-dwarf/test2.so'>
Support reading and comparing soname from ELF files Libabigail's DWARF reader doesn't read the DT_SONAME tag from the .dynamic section. The abigail::corpus type doesn't have a property for that tag either. And the comparison engine doesn't take that tag in when comparing corpora. This patch modifies the DWARF reader to read the DT_SONAME and DT_NEEDED tags from the .dynamic section. The value of DT_SONAME tag is then saved in the new corpus property accessed by the new abigail::corpus::get_soname() accessor. The comparison engine has also been modified to compare the sonames of two corpora being compared. Note that the value of the DT_NEEDED elf tag is saved in a new corpus property that is accessed via the new abigail::corpus::get_needed() getter. This property is not used yet. This patch also adds a unit test for this new feature. * include/abg-corpus.h (corpus::{get_needed, set_needed, get_soname, set_soname}): Declare new accessors. * src/abg-corpus.cc (corpus::priv::{needed, soname}): New data members. (corpus::{get_needed, set_needed, get_soname, set_soname}): Define new accessors. (corpus::is_empty): Take dt_needed and dt_soname in account in computing empty-ness. * src/abg-dwarf-reader.cc (read_context::{dt_needed_, dt_soname_}): New data members. (read_context::{dt_needed, dt_soname}): New accessors. (read_context::load_dt_soname_and_needed): New member function. (read_corpus_from_elf): Call the new read_context::load_dt_soname_and_needed() to read the dt_soname and dt_needed tags. Set them to the corpus. * include/abg-comparison.h (diff_context::show_soname_change): Declare new accessors. * src/abg-comparison.cc (diff_context::priv::show_soname_change_): New data member. (diff_context::priv::priv): Initialize the new data member diff_context::priv::show_soname_change_. (diff_context::show_soname_change): Define new accessors. (corpus_diff::priv::sonames_equal_): New data member. (corpus_diff::priv::priv): Initialize the new data member corpus_diff::priv::sonames_equal_. (corpus_diff::length): Take the new priv_->sonames_equals_ data member in account. (corpus_diff::{report, priv::emit_diff_stats}): If the sonames changed and we are allowed to report it, then report it. (compute_diff): In the variant for corpus_diff, do not forget to compare the sonames. * src/abg-reader.cc (build_needed, read_elf_needed_from_input): Define new static functions. (read_corpus_from_input): Read the 'soname' attribute from the 'abi-corpus' xml element node. * src/abg-writer.cc (write_elf_needed): Define new static function. (write_corpus_to_native_xml): Write a new 'elf-needed' xml element node that contains one xml 'dependency' element node per dependency to emit. This uses the new write_elf_needed() function above. * tests/data/test-diff-dwarf/libtest19-soname-v0.so: New test input data. * tests/data/test-diff-dwarf/libtest19-soname-v1.so: Likewise. * tests/data/test-diff-dwarf/test19-soname-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test19-soname-v0.c: Source code of the first binary above. * tests/data/test-diff-dwarf/test19-soname-v1.c: Source code of the second binary above. * tests/test-diff-dwarf.cc (in_out_specs): Add the test input above to the list of test input to run this harness on. * tests/data/Makefile.am: Add the new test input data above. * tests/data/test-read-dwarf/test{0,1}.abi: Adjust. * tests/data/test-read-dwarf/test{2,3,4,6,}.so.abi: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-07 20:01:20 +00:00
<elf-needed>
<dependency name='libstdc++.so.6'/>
<dependency name='libm.so.6'/>
<dependency name='libgcc_s.so.1'/>
<dependency name='libc.so.6'/>
</elf-needed>
Add a symbol database to the ABI Corpus & support symbol aliases * include/abg-corpus.h (corpus::{g,s}et_{fun,var}_symbol_map{_sptr}): Declare new accessors. (corpus::lookup_{variable,function}_symbol): Declare new member functions. * src/abg-corpus.cc (corpus::{g,s}et_{fun,var}_symbol_map{_sptr}): Define new accessors. (corpus::lookup_{variable,function}_symbol): Define new member functions. * include/abg-ir.h (string_elf_symbol_sptr_map_type) (string_elf_symbol_sptr_map_sptr, elf_symbols) (string_elf_symbols_map_type, string_elf_symbols_map_sptr): New convenience typedefs. (elf_symbol::{get_main_symbol, is_main_symbol, get_next_alias, has_aliases, add_alias, get_id_string, get_name_and_version_from_id, operator=}): Declare new member functions. * src/abg-ir.cc (elf_symbol::{get_main_symbol, is_main_symbol, get_next_alias, has_aliases, add_alias, get_id_string, get_name_and_version_from_id, operator=}): Define new member functions. * include/abg-reader.h (read_corpus_from_file): Take a shared pointer to corpus. * src/abg-reader.cc (read_context::{g,s}et_corpus): Define these. (build_elf_symbol_db, build_elf_symbol_from_reference) (read_symbol_db_from_input): Define new functions. (read_corpus_from_input): Adjust. Make it read symbol databases. (build_elf_symbol): Harden this. (build_{var,function}_decl): Read the symbol reference. Do not read the local symbol serialization anymore. (read_corpus_from_archive): Adjust. (read_corpus_from_file): Take a reference to a shared pointer to corpus, rather than a reference to the corpus. (read_corpus_from_native_xml): Only keep the overload that returns a corpus. Set the current context with the corpus. * src/abg-dwarf-reader.cc (addr_elf_symbol_sptr_map_type) (addr_elf_symbol_sptr_map_sptr): New convenience typedefs. (read_context::{fun_sym_addr_sym_index_map_, var_sym_addr_sym_index_map_): Remove. (read_context::{fun,var}_addr_sym_map_): New. Replace the above that got removed. (read_context::{var,fun}_syms_): New. (read_context::lookup_elf_{fn,var}_symbol_from_address): Adjust. (read_context::{fun,var}_addr_sym_map{_sptr}): New. (read_context::{fun,var}_syms{_sptr}): New. (read_context::load_symbol_maps): Replace read_context::load_symbol_addr_to_index_maps. Adjust to load all the new maps. (read_context::maybe_load_symbol_maps): New. (read_debug_info_into_corpus): Renamed build_corpus into this. Update to load symbol maps and set it to the corpus. * src/abg-writer.cc (write_context::get_fun_symbol_map): New accessor. (write_elf_symbol_aliases, write_elf_symbol_reference) (write_elf_symbols_table): Define new static functions. (write_var_decl): Write the reference to the underlying symbol of the variable. Do not write the full symbol here anymore. (write_function_decl): Likewise, write the reference to the underlying symbol of the function. Do not write the full symbol here anymore. (write_corpus_to_native_xml): Write the symbol databases at the beginning of the corpus document. * src/abg-comparison.cc (corpus_diff::priv::ensure_lookup_tables_populated): Now that the corpus has symbols, check if a the symbol of an allegedly deleted function (resp. variable) is deleted; if not, then do not report the function (resp. variable) as deleted. Similarly, check if the symbol of an allegedly added function (resp. variable) is added. if not, the do not report the function (resp. variable) as added. * tests/test-write-read-archive.cc (main): Adjust. * tools/biar.cc (extract_tus_from_archive): Likewise. * tests/data/test-diff-filter/test9-report.txt: Adjust. * tests/data/test-read-dwarf/test0.abi: Likewise. * tests/data/test-read-dwarf/test1.abi: Likewise. * tests/data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-28 14:33:35 +00:00
<elf-function-symbols>
<elf-symbol name='_ZN10first_typeC1Ev' type='func-type' binding='global-binding' alias='_ZN10first_typeC2Ev' is-defined='yes'/>
<elf-symbol name='_ZN10first_typeC2Ev' type='func-type' binding='global-binding' is-defined='yes'/>
<elf-symbol name='_ZN11second_typeC1Ev' type='func-type' binding='global-binding' alias='_ZN11second_typeC2Ev' is-defined='yes'/>
Add a symbol database to the ABI Corpus & support symbol aliases * include/abg-corpus.h (corpus::{g,s}et_{fun,var}_symbol_map{_sptr}): Declare new accessors. (corpus::lookup_{variable,function}_symbol): Declare new member functions. * src/abg-corpus.cc (corpus::{g,s}et_{fun,var}_symbol_map{_sptr}): Define new accessors. (corpus::lookup_{variable,function}_symbol): Define new member functions. * include/abg-ir.h (string_elf_symbol_sptr_map_type) (string_elf_symbol_sptr_map_sptr, elf_symbols) (string_elf_symbols_map_type, string_elf_symbols_map_sptr): New convenience typedefs. (elf_symbol::{get_main_symbol, is_main_symbol, get_next_alias, has_aliases, add_alias, get_id_string, get_name_and_version_from_id, operator=}): Declare new member functions. * src/abg-ir.cc (elf_symbol::{get_main_symbol, is_main_symbol, get_next_alias, has_aliases, add_alias, get_id_string, get_name_and_version_from_id, operator=}): Define new member functions. * include/abg-reader.h (read_corpus_from_file): Take a shared pointer to corpus. * src/abg-reader.cc (read_context::{g,s}et_corpus): Define these. (build_elf_symbol_db, build_elf_symbol_from_reference) (read_symbol_db_from_input): Define new functions. (read_corpus_from_input): Adjust. Make it read symbol databases. (build_elf_symbol): Harden this. (build_{var,function}_decl): Read the symbol reference. Do not read the local symbol serialization anymore. (read_corpus_from_archive): Adjust. (read_corpus_from_file): Take a reference to a shared pointer to corpus, rather than a reference to the corpus. (read_corpus_from_native_xml): Only keep the overload that returns a corpus. Set the current context with the corpus. * src/abg-dwarf-reader.cc (addr_elf_symbol_sptr_map_type) (addr_elf_symbol_sptr_map_sptr): New convenience typedefs. (read_context::{fun_sym_addr_sym_index_map_, var_sym_addr_sym_index_map_): Remove. (read_context::{fun,var}_addr_sym_map_): New. Replace the above that got removed. (read_context::{var,fun}_syms_): New. (read_context::lookup_elf_{fn,var}_symbol_from_address): Adjust. (read_context::{fun,var}_addr_sym_map{_sptr}): New. (read_context::{fun,var}_syms{_sptr}): New. (read_context::load_symbol_maps): Replace read_context::load_symbol_addr_to_index_maps. Adjust to load all the new maps. (read_context::maybe_load_symbol_maps): New. (read_debug_info_into_corpus): Renamed build_corpus into this. Update to load symbol maps and set it to the corpus. * src/abg-writer.cc (write_context::get_fun_symbol_map): New accessor. (write_elf_symbol_aliases, write_elf_symbol_reference) (write_elf_symbols_table): Define new static functions. (write_var_decl): Write the reference to the underlying symbol of the variable. Do not write the full symbol here anymore. (write_function_decl): Likewise, write the reference to the underlying symbol of the function. Do not write the full symbol here anymore. (write_corpus_to_native_xml): Write the symbol databases at the beginning of the corpus document. * src/abg-comparison.cc (corpus_diff::priv::ensure_lookup_tables_populated): Now that the corpus has symbols, check if a the symbol of an allegedly deleted function (resp. variable) is deleted; if not, then do not report the function (resp. variable) as deleted. Similarly, check if the symbol of an allegedly added function (resp. variable) is added. if not, the do not report the function (resp. variable) as added. * tests/test-write-read-archive.cc (main): Adjust. * tools/biar.cc (extract_tus_from_archive): Likewise. * tests/data/test-diff-filter/test9-report.txt: Adjust. * tests/data/test-read-dwarf/test0.abi: Likewise. * tests/data/test-read-dwarf/test1.abi: Likewise. * tests/data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-28 14:33:35 +00:00
<elf-symbol name='_ZN11second_typeC2Ev' type='func-type' binding='global-binding' is-defined='yes'/>
<elf-symbol name='_ZN1a16build_first_typeEv' type='func-type' binding='global-binding' is-defined='yes'/>
<elf-symbol name='_ZN1a17build_second_typeEv' type='func-type' binding='global-binding' is-defined='yes'/>
<elf-symbol name='_fini' type='func-type' binding='global-binding' is-defined='yes'/>
<elf-symbol name='_init' type='func-type' binding='global-binding' is-defined='yes'/>
Add a symbol database to the ABI Corpus & support symbol aliases * include/abg-corpus.h (corpus::{g,s}et_{fun,var}_symbol_map{_sptr}): Declare new accessors. (corpus::lookup_{variable,function}_symbol): Declare new member functions. * src/abg-corpus.cc (corpus::{g,s}et_{fun,var}_symbol_map{_sptr}): Define new accessors. (corpus::lookup_{variable,function}_symbol): Define new member functions. * include/abg-ir.h (string_elf_symbol_sptr_map_type) (string_elf_symbol_sptr_map_sptr, elf_symbols) (string_elf_symbols_map_type, string_elf_symbols_map_sptr): New convenience typedefs. (elf_symbol::{get_main_symbol, is_main_symbol, get_next_alias, has_aliases, add_alias, get_id_string, get_name_and_version_from_id, operator=}): Declare new member functions. * src/abg-ir.cc (elf_symbol::{get_main_symbol, is_main_symbol, get_next_alias, has_aliases, add_alias, get_id_string, get_name_and_version_from_id, operator=}): Define new member functions. * include/abg-reader.h (read_corpus_from_file): Take a shared pointer to corpus. * src/abg-reader.cc (read_context::{g,s}et_corpus): Define these. (build_elf_symbol_db, build_elf_symbol_from_reference) (read_symbol_db_from_input): Define new functions. (read_corpus_from_input): Adjust. Make it read symbol databases. (build_elf_symbol): Harden this. (build_{var,function}_decl): Read the symbol reference. Do not read the local symbol serialization anymore. (read_corpus_from_archive): Adjust. (read_corpus_from_file): Take a reference to a shared pointer to corpus, rather than a reference to the corpus. (read_corpus_from_native_xml): Only keep the overload that returns a corpus. Set the current context with the corpus. * src/abg-dwarf-reader.cc (addr_elf_symbol_sptr_map_type) (addr_elf_symbol_sptr_map_sptr): New convenience typedefs. (read_context::{fun_sym_addr_sym_index_map_, var_sym_addr_sym_index_map_): Remove. (read_context::{fun,var}_addr_sym_map_): New. Replace the above that got removed. (read_context::{var,fun}_syms_): New. (read_context::lookup_elf_{fn,var}_symbol_from_address): Adjust. (read_context::{fun,var}_addr_sym_map{_sptr}): New. (read_context::{fun,var}_syms{_sptr}): New. (read_context::load_symbol_maps): Replace read_context::load_symbol_addr_to_index_maps. Adjust to load all the new maps. (read_context::maybe_load_symbol_maps): New. (read_debug_info_into_corpus): Renamed build_corpus into this. Update to load symbol maps and set it to the corpus. * src/abg-writer.cc (write_context::get_fun_symbol_map): New accessor. (write_elf_symbol_aliases, write_elf_symbol_reference) (write_elf_symbols_table): Define new static functions. (write_var_decl): Write the reference to the underlying symbol of the variable. Do not write the full symbol here anymore. (write_function_decl): Likewise, write the reference to the underlying symbol of the function. Do not write the full symbol here anymore. (write_corpus_to_native_xml): Write the symbol databases at the beginning of the corpus document. * src/abg-comparison.cc (corpus_diff::priv::ensure_lookup_tables_populated): Now that the corpus has symbols, check if a the symbol of an allegedly deleted function (resp. variable) is deleted; if not, then do not report the function (resp. variable) as deleted. Similarly, check if the symbol of an allegedly added function (resp. variable) is added. if not, the do not report the function (resp. variable) as added. * tests/test-write-read-archive.cc (main): Adjust. * tools/biar.cc (extract_tus_from_archive): Likewise. * tests/data/test-diff-filter/test9-report.txt: Adjust. * tests/data/test-read-dwarf/test0.abi: Likewise. * tests/data/test-read-dwarf/test1.abi: Likewise. * tests/data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-28 14:33:35 +00:00
</elf-function-symbols>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
<abi-instr version='1.0' address-size='64' path='test2-0.cc'>
<class-decl name='first_type' size-in-bits='64' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='4' column='1' id='type-id-1'>
<data-member access='public' layout-offset-in-bits='0'>
<var-decl name='member0' type-id='type-id-2' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='6' column='1'/>
</data-member>
<data-member access='public' layout-offset-in-bits='32'>
<var-decl name='member1' type-id='type-id-3' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='7' column='1'/>
</data-member>
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
<member-function access='public' constructor='yes'>
Type read from DWARF don't have alignment information Types read from DWARF don't have any alignment information so we shouldn't try to guess it, especially for structures. So this patch sets the alignment to zero in that case. This helps remove some spurious alignment changes detected by abidiff just because in some cases we fail to guess that. In the process, I noticed that when calculating the hash value of a given data member, we were not including the hash value of its context. This led to mistakenly considering some data member changes as redundant. So the patch fixes that too. * src/abg-dwarf-reader.cc (build_type_decl) (build_class_type_and_add_to_ir, build_pointer_type_def) (build_reference_type, build_function_decl): Set the alignment for native types, class, reference and function type to zero, effectively meaning that they don't have alignment information. * src/abg-hash.cc (var_decl::hash::operator): Take the hash value of the data member context in account when computing the hash value of a given data member. * tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test10-report.txt: Likewise. * tests/data/test-diff-dwarf/test13-report.txt: Likewise. * tests/data/test-diff-dwarf/test22-changed-parm-c-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: Likewise. * tests/data/test-diff-dwarf/test8-report.txt: Likewise. * tests/data/test-diff-dwarf/test9-report.txt: Likewise. * tests/data/test-diff-filter/test13-report.txt: Likewise. * tests/data/test-diff-filter/test6-report.txt: Likewise. * tests/data/test-diff-suppr/test9-changed-parm-c-report-0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * 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>
2015-05-24 15:16:41 +00:00
<function-decl name='first_type' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='9' column='1' visibility='default' binding='global' size-in-bits='64'>
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
<parameter type-id='type-id-4' is-artificial='yes'/>
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
<return type-id='type-id-5'/>
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
</function-decl>
</member-function>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
<member-function access='public' constructor='yes'>
Type read from DWARF don't have alignment information Types read from DWARF don't have any alignment information so we shouldn't try to guess it, especially for structures. So this patch sets the alignment to zero in that case. This helps remove some spurious alignment changes detected by abidiff just because in some cases we fail to guess that. In the process, I noticed that when calculating the hash value of a given data member, we were not including the hash value of its context. This led to mistakenly considering some data member changes as redundant. So the patch fixes that too. * src/abg-dwarf-reader.cc (build_type_decl) (build_class_type_and_add_to_ir, build_pointer_type_def) (build_reference_type, build_function_decl): Set the alignment for native types, class, reference and function type to zero, effectively meaning that they don't have alignment information. * src/abg-hash.cc (var_decl::hash::operator): Take the hash value of the data member context in account when computing the hash value of a given data member. * tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test10-report.txt: Likewise. * tests/data/test-diff-dwarf/test13-report.txt: Likewise. * tests/data/test-diff-dwarf/test22-changed-parm-c-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: Likewise. * tests/data/test-diff-dwarf/test8-report.txt: Likewise. * tests/data/test-diff-dwarf/test9-report.txt: Likewise. * tests/data/test-diff-filter/test13-report.txt: Likewise. * tests/data/test-diff-filter/test6-report.txt: Likewise. * tests/data/test-diff-suppr/test9-changed-parm-c-report-0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * 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>
2015-05-24 15:16:41 +00:00
<function-decl name='first_type' mangled-name='_ZN10first_typeC1Ev' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='9' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN10first_typeC1Ev'>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
<parameter type-id='type-id-4' is-artificial='yes'/>
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
<return type-id='type-id-5'/>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
</function-decl>
</member-function>
</class-decl>
Type read from DWARF don't have alignment information Types read from DWARF don't have any alignment information so we shouldn't try to guess it, especially for structures. So this patch sets the alignment to zero in that case. This helps remove some spurious alignment changes detected by abidiff just because in some cases we fail to guess that. In the process, I noticed that when calculating the hash value of a given data member, we were not including the hash value of its context. This led to mistakenly considering some data member changes as redundant. So the patch fixes that too. * src/abg-dwarf-reader.cc (build_type_decl) (build_class_type_and_add_to_ir, build_pointer_type_def) (build_reference_type, build_function_decl): Set the alignment for native types, class, reference and function type to zero, effectively meaning that they don't have alignment information. * src/abg-hash.cc (var_decl::hash::operator): Take the hash value of the data member context in account when computing the hash value of a given data member. * tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test10-report.txt: Likewise. * tests/data/test-diff-dwarf/test13-report.txt: Likewise. * tests/data/test-diff-dwarf/test22-changed-parm-c-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: Likewise. * tests/data/test-diff-dwarf/test8-report.txt: Likewise. * tests/data/test-diff-dwarf/test9-report.txt: Likewise. * tests/data/test-diff-filter/test13-report.txt: Likewise. * tests/data/test-diff-filter/test6-report.txt: Likewise. * tests/data/test-diff-suppr/test9-changed-parm-c-report-0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * 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>
2015-05-24 15:16:41 +00:00
<type-decl name='int' size-in-bits='32' id='type-id-6'/>
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
<typedef-decl name='integer' type-id='type-id-6' id='type-id-2'/>
Type read from DWARF don't have alignment information Types read from DWARF don't have any alignment information so we shouldn't try to guess it, especially for structures. So this patch sets the alignment to zero in that case. This helps remove some spurious alignment changes detected by abidiff just because in some cases we fail to guess that. In the process, I noticed that when calculating the hash value of a given data member, we were not including the hash value of its context. This led to mistakenly considering some data member changes as redundant. So the patch fixes that too. * src/abg-dwarf-reader.cc (build_type_decl) (build_class_type_and_add_to_ir, build_pointer_type_def) (build_reference_type, build_function_decl): Set the alignment for native types, class, reference and function type to zero, effectively meaning that they don't have alignment information. * src/abg-hash.cc (var_decl::hash::operator): Take the hash value of the data member context in account when computing the hash value of a given data member. * tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test10-report.txt: Likewise. * tests/data/test-diff-dwarf/test13-report.txt: Likewise. * tests/data/test-diff-dwarf/test22-changed-parm-c-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: Likewise. * tests/data/test-diff-dwarf/test8-report.txt: Likewise. * tests/data/test-diff-dwarf/test9-report.txt: Likewise. * tests/data/test-diff-filter/test13-report.txt: Likewise. * tests/data/test-diff-filter/test6-report.txt: Likewise. * tests/data/test-diff-suppr/test9-changed-parm-c-report-0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * 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>
2015-05-24 15:16:41 +00:00
<type-decl name='unsigned char' size-in-bits='8' id='type-id-7'/>
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
<typedef-decl name='character' type-id='type-id-7' id='type-id-3'/>
<type-decl name='void' id='type-id-5'/>
Type read from DWARF don't have alignment information Types read from DWARF don't have any alignment information so we shouldn't try to guess it, especially for structures. So this patch sets the alignment to zero in that case. This helps remove some spurious alignment changes detected by abidiff just because in some cases we fail to guess that. In the process, I noticed that when calculating the hash value of a given data member, we were not including the hash value of its context. This led to mistakenly considering some data member changes as redundant. So the patch fixes that too. * src/abg-dwarf-reader.cc (build_type_decl) (build_class_type_and_add_to_ir, build_pointer_type_def) (build_reference_type, build_function_decl): Set the alignment for native types, class, reference and function type to zero, effectively meaning that they don't have alignment information. * src/abg-hash.cc (var_decl::hash::operator): Take the hash value of the data member context in account when computing the hash value of a given data member. * tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test10-report.txt: Likewise. * tests/data/test-diff-dwarf/test13-report.txt: Likewise. * tests/data/test-diff-dwarf/test22-changed-parm-c-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: Likewise. * tests/data/test-diff-dwarf/test8-report.txt: Likewise. * tests/data/test-diff-dwarf/test9-report.txt: Likewise. * tests/data/test-diff-filter/test13-report.txt: Likewise. * tests/data/test-diff-filter/test6-report.txt: Likewise. * tests/data/test-diff-suppr/test9-changed-parm-c-report-0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * 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>
2015-05-24 15:16:41 +00:00
<pointer-type-def type-id='type-id-1' size-in-bits='64' id='type-id-4'/>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
<namespace-decl name='a'>
Type read from DWARF don't have alignment information Types read from DWARF don't have any alignment information so we shouldn't try to guess it, especially for structures. So this patch sets the alignment to zero in that case. This helps remove some spurious alignment changes detected by abidiff just because in some cases we fail to guess that. In the process, I noticed that when calculating the hash value of a given data member, we were not including the hash value of its context. This led to mistakenly considering some data member changes as redundant. So the patch fixes that too. * src/abg-dwarf-reader.cc (build_type_decl) (build_class_type_and_add_to_ir, build_pointer_type_def) (build_reference_type, build_function_decl): Set the alignment for native types, class, reference and function type to zero, effectively meaning that they don't have alignment information. * src/abg-hash.cc (var_decl::hash::operator): Take the hash value of the data member context in account when computing the hash value of a given data member. * tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test10-report.txt: Likewise. * tests/data/test-diff-dwarf/test13-report.txt: Likewise. * tests/data/test-diff-dwarf/test22-changed-parm-c-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: Likewise. * tests/data/test-diff-dwarf/test8-report.txt: Likewise. * tests/data/test-diff-dwarf/test9-report.txt: Likewise. * tests/data/test-diff-filter/test13-report.txt: Likewise. * tests/data/test-diff-filter/test6-report.txt: Likewise. * tests/data/test-diff-suppr/test9-changed-parm-c-report-0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * 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>
2015-05-24 15:16:41 +00:00
<function-decl name='build_first_type' mangled-name='_ZN1a16build_first_typeEv' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2-0.cc' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN1a16build_first_typeEv'>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
<return type-id='type-id-4'/>
</function-decl>
</namespace-decl>
</abi-instr>
<abi-instr version='1.0' address-size='64' path='test2-1.cc'>
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
<class-decl name='second_type' size-in-bits='64' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='12' column='1' id='type-id-8'>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
<data-member access='public' layout-offset-in-bits='0'>
Delay non-complete class type resolution up to end of corpus reading From the DWARF emitted by GCC 4.4.7 for libstdc++ we encountered an interesting construct. A non-complete version of std::runtime_error is declared in libstdc++-v3/src/functexcept.cc and is represented in DWARF as: [ 37344] class_type name (strp) "runtime_error" declaration (flag) Then a bit later, that *non-complete* class is used as a base class for a class, *without* being fully defined! This shouldn't happen but, well, it does: [ 3b3a1] class_type specification (ref4) [ 3733e] byte_size (data1) 16 decl_file (data1) 5 decl_line (data1) 141 containing_type (ref4) [ 3734a] sibling (ref4) [3b405] [ 3b3b1] inheritance type (ref4) [ 37344] <---- here. The thing is that, later, in another translation unit (libstdc++-v3/src/stdexcept.cc), that same class is defined fully: [ 7e9f9] class_type name (strp) "runtime_error" declaration (flag) [...] [ 80c95] class_type specification (ref4) [ 7e9f9] byte_size (data1) 16 decl_file (data1) 4 decl_line (data1) 108 containing_type (ref4) [ 7e9ff] sibling (ref4) [ 80d2b] [...] <---------- and the definition goes here. But then you see that the DIE offset of the "version" of the runtime_error class that is "defined" libstdc++-v3/src/stdexcept.cc in is different from the version that is only declared in libstdc++-v3/src/functexcept.cc. But virtue of the "One Definition Rule", we can assume that they designate the same type. But still, runtime_error should have been defined in libstdc++-v3/src/stdexcept.cc. Anyhow, libabigail needs to be able to handle this. That is, it needs to wait until the entire ABI corpus is loaded from DWARF, then lookup the definition of all the non-complete types we have encountered. And then only after that non-complete type resolution has taken place, we can proceed with type canonicalizing, rather than doing it after the loading of each translation unit like what we were doing previously. This is what this patch does. * include/abg-fwd.h (lookup_type_in_corpus): Declare new function. * src/abg-corpus.cc (lookup_type_in_corpus): Define new function here. * include/abg-ir.h (function_types_type): Declare new typedef. (translation_unit::get_canonical_function_type): Remove member function. (translation_unit::bind_function_type_life_time): Declare new member function. (classes_type): New typedef. * src/abg-ir.cc (translation_unit::priv::canonical_function_types_): Remove data member. (translation_unit::priv::function_types): New data member. (translation_unit::get_canonical_function_type): Remove this function definition. (translation_unit::bind_function_type_life_time): New function definition. (lookup_node_in_scope): Ensure that the type returned is complete. * src/abg-dwarf-reader.cc (string_classes_map): New typedef. (read_context::decl_only_classes_map_): New data member. (read_context::declaration_only_classes): New accessor. (read_context::{maybe_schedule_declaration_only_class_for_resolution, is_decl_only_class_scheduled_for_resolution, resolve_declaration_only_classes, current_elf_file_is_executable, current_elf_file_is_dso}): Define new member functions. (read_context::clear_per_translation_unit_data): Do not clear the data structures that associate DIEs to decls/types or that contain the types to canonicalize here. Rather, clear them ... (read_context::clear_per_corpus_data): ... here instead. (read_context::build_translation_unit_and_add_to_ir): Do not perform late type canonicalizing here. Rather, do it ... (read_debug_info_into_corpus): ... here instead. And before that, call read_context::clear_per_corpus_data() and the new read_context::resolve_declaration_only_classes() here. (build_class_type_and_add_to_ir): Schedule the non-complete types for resolution to complete types. Assert that base classes that are non-complete are scheduled to be completed. (build_function_decl): Do not try to canonicalize function types this early, systematically. Now, all the non-complete types needs to be completed before starting canonicalizing. So let function types go through the normal processes of deciding when to canonicalize them. But then, bind the life time of the function type to the life time of the current translation unit. (maybe_canonicalize_type): If a class type is non-complete, schedule it for late canonicalizing. * src/abg-hash.cc (class_decl::hash::operator()(const class_decl&) const): During hashing, a base class should be complete. * src/abg-reader.cc (read_context::clear_per_translation_unit_data): Do not clear id/xml node, and type maps here. Rather, clear it ... (read_context::clear_per_corpus_data): ... here instead. (read_translation_unit_from_input): Do not perform late canonicalizing here. Rather, do it ... (read_corpus_from_input): ... here. Also, call the new read_context::clear_per_corpus_data() here. (build_function_decl): Do not canonicalize function types here so early. Rather, bind the life time of the function type to the life time of the translation unit. * src/abg-writer.cc (write_translation_unit): Do not clear the type/ID map here. * tests/data/test-read-dwarf/test2.so.abi: Adjust test input. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-17 09:54:12 +00:00
<var-decl name='member0' type-id='type-id-2' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='14' column='1'/>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
</data-member>
<data-member access='public' layout-offset-in-bits='32'>
Delay non-complete class type resolution up to end of corpus reading From the DWARF emitted by GCC 4.4.7 for libstdc++ we encountered an interesting construct. A non-complete version of std::runtime_error is declared in libstdc++-v3/src/functexcept.cc and is represented in DWARF as: [ 37344] class_type name (strp) "runtime_error" declaration (flag) Then a bit later, that *non-complete* class is used as a base class for a class, *without* being fully defined! This shouldn't happen but, well, it does: [ 3b3a1] class_type specification (ref4) [ 3733e] byte_size (data1) 16 decl_file (data1) 5 decl_line (data1) 141 containing_type (ref4) [ 3734a] sibling (ref4) [3b405] [ 3b3b1] inheritance type (ref4) [ 37344] <---- here. The thing is that, later, in another translation unit (libstdc++-v3/src/stdexcept.cc), that same class is defined fully: [ 7e9f9] class_type name (strp) "runtime_error" declaration (flag) [...] [ 80c95] class_type specification (ref4) [ 7e9f9] byte_size (data1) 16 decl_file (data1) 4 decl_line (data1) 108 containing_type (ref4) [ 7e9ff] sibling (ref4) [ 80d2b] [...] <---------- and the definition goes here. But then you see that the DIE offset of the "version" of the runtime_error class that is "defined" libstdc++-v3/src/stdexcept.cc in is different from the version that is only declared in libstdc++-v3/src/functexcept.cc. But virtue of the "One Definition Rule", we can assume that they designate the same type. But still, runtime_error should have been defined in libstdc++-v3/src/stdexcept.cc. Anyhow, libabigail needs to be able to handle this. That is, it needs to wait until the entire ABI corpus is loaded from DWARF, then lookup the definition of all the non-complete types we have encountered. And then only after that non-complete type resolution has taken place, we can proceed with type canonicalizing, rather than doing it after the loading of each translation unit like what we were doing previously. This is what this patch does. * include/abg-fwd.h (lookup_type_in_corpus): Declare new function. * src/abg-corpus.cc (lookup_type_in_corpus): Define new function here. * include/abg-ir.h (function_types_type): Declare new typedef. (translation_unit::get_canonical_function_type): Remove member function. (translation_unit::bind_function_type_life_time): Declare new member function. (classes_type): New typedef. * src/abg-ir.cc (translation_unit::priv::canonical_function_types_): Remove data member. (translation_unit::priv::function_types): New data member. (translation_unit::get_canonical_function_type): Remove this function definition. (translation_unit::bind_function_type_life_time): New function definition. (lookup_node_in_scope): Ensure that the type returned is complete. * src/abg-dwarf-reader.cc (string_classes_map): New typedef. (read_context::decl_only_classes_map_): New data member. (read_context::declaration_only_classes): New accessor. (read_context::{maybe_schedule_declaration_only_class_for_resolution, is_decl_only_class_scheduled_for_resolution, resolve_declaration_only_classes, current_elf_file_is_executable, current_elf_file_is_dso}): Define new member functions. (read_context::clear_per_translation_unit_data): Do not clear the data structures that associate DIEs to decls/types or that contain the types to canonicalize here. Rather, clear them ... (read_context::clear_per_corpus_data): ... here instead. (read_context::build_translation_unit_and_add_to_ir): Do not perform late type canonicalizing here. Rather, do it ... (read_debug_info_into_corpus): ... here instead. And before that, call read_context::clear_per_corpus_data() and the new read_context::resolve_declaration_only_classes() here. (build_class_type_and_add_to_ir): Schedule the non-complete types for resolution to complete types. Assert that base classes that are non-complete are scheduled to be completed. (build_function_decl): Do not try to canonicalize function types this early, systematically. Now, all the non-complete types needs to be completed before starting canonicalizing. So let function types go through the normal processes of deciding when to canonicalize them. But then, bind the life time of the function type to the life time of the current translation unit. (maybe_canonicalize_type): If a class type is non-complete, schedule it for late canonicalizing. * src/abg-hash.cc (class_decl::hash::operator()(const class_decl&) const): During hashing, a base class should be complete. * src/abg-reader.cc (read_context::clear_per_translation_unit_data): Do not clear id/xml node, and type maps here. Rather, clear it ... (read_context::clear_per_corpus_data): ... here instead. (read_translation_unit_from_input): Do not perform late canonicalizing here. Rather, do it ... (read_corpus_from_input): ... here. Also, call the new read_context::clear_per_corpus_data() here. (build_function_decl): Do not canonicalize function types here so early. Rather, bind the life time of the function type to the life time of the translation unit. * src/abg-writer.cc (write_translation_unit): Do not clear the type/ID map here. * tests/data/test-read-dwarf/test2.so.abi: Adjust test input. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-17 09:54:12 +00:00
<var-decl name='member1' type-id='type-id-3' visibility='default' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='15' column='1'/>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
</data-member>
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
<member-function access='public' constructor='yes'>
Type read from DWARF don't have alignment information Types read from DWARF don't have any alignment information so we shouldn't try to guess it, especially for structures. So this patch sets the alignment to zero in that case. This helps remove some spurious alignment changes detected by abidiff just because in some cases we fail to guess that. In the process, I noticed that when calculating the hash value of a given data member, we were not including the hash value of its context. This led to mistakenly considering some data member changes as redundant. So the patch fixes that too. * src/abg-dwarf-reader.cc (build_type_decl) (build_class_type_and_add_to_ir, build_pointer_type_def) (build_reference_type, build_function_decl): Set the alignment for native types, class, reference and function type to zero, effectively meaning that they don't have alignment information. * src/abg-hash.cc (var_decl::hash::operator): Take the hash value of the data member context in account when computing the hash value of a given data member. * tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test10-report.txt: Likewise. * tests/data/test-diff-dwarf/test13-report.txt: Likewise. * tests/data/test-diff-dwarf/test22-changed-parm-c-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: Likewise. * tests/data/test-diff-dwarf/test8-report.txt: Likewise. * tests/data/test-diff-dwarf/test9-report.txt: Likewise. * tests/data/test-diff-filter/test13-report.txt: Likewise. * tests/data/test-diff-filter/test6-report.txt: Likewise. * tests/data/test-diff-suppr/test9-changed-parm-c-report-0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * 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>
2015-05-24 15:16:41 +00:00
<function-decl name='second_type' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'>
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
<parameter type-id='type-id-9' is-artificial='yes'/>
<return type-id='type-id-5'/>
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
</function-decl>
</member-function>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
<member-function access='public' constructor='yes'>
Type read from DWARF don't have alignment information Types read from DWARF don't have any alignment information so we shouldn't try to guess it, especially for structures. So this patch sets the alignment to zero in that case. This helps remove some spurious alignment changes detected by abidiff just because in some cases we fail to guess that. In the process, I noticed that when calculating the hash value of a given data member, we were not including the hash value of its context. This led to mistakenly considering some data member changes as redundant. So the patch fixes that too. * src/abg-dwarf-reader.cc (build_type_decl) (build_class_type_and_add_to_ir, build_pointer_type_def) (build_reference_type, build_function_decl): Set the alignment for native types, class, reference and function type to zero, effectively meaning that they don't have alignment information. * src/abg-hash.cc (var_decl::hash::operator): Take the hash value of the data member context in account when computing the hash value of a given data member. * tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test10-report.txt: Likewise. * tests/data/test-diff-dwarf/test13-report.txt: Likewise. * tests/data/test-diff-dwarf/test22-changed-parm-c-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: Likewise. * tests/data/test-diff-dwarf/test8-report.txt: Likewise. * tests/data/test-diff-dwarf/test9-report.txt: Likewise. * tests/data/test-diff-filter/test13-report.txt: Likewise. * tests/data/test-diff-filter/test6-report.txt: Likewise. * tests/data/test-diff-suppr/test9-changed-parm-c-report-0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * 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>
2015-05-24 15:16:41 +00:00
<function-decl name='second_type' mangled-name='_ZN11second_typeC1Ev' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN11second_typeC1Ev'>
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
<parameter type-id='type-id-9' is-artificial='yes'/>
<return type-id='type-id-5'/>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
</function-decl>
</member-function>
</class-decl>
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
<type-decl name='void' id='type-id-5'/>
Type read from DWARF don't have alignment information Types read from DWARF don't have any alignment information so we shouldn't try to guess it, especially for structures. So this patch sets the alignment to zero in that case. This helps remove some spurious alignment changes detected by abidiff just because in some cases we fail to guess that. In the process, I noticed that when calculating the hash value of a given data member, we were not including the hash value of its context. This led to mistakenly considering some data member changes as redundant. So the patch fixes that too. * src/abg-dwarf-reader.cc (build_type_decl) (build_class_type_and_add_to_ir, build_pointer_type_def) (build_reference_type, build_function_decl): Set the alignment for native types, class, reference and function type to zero, effectively meaning that they don't have alignment information. * src/abg-hash.cc (var_decl::hash::operator): Take the hash value of the data member context in account when computing the hash value of a given data member. * tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test10-report.txt: Likewise. * tests/data/test-diff-dwarf/test13-report.txt: Likewise. * tests/data/test-diff-dwarf/test22-changed-parm-c-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: Likewise. * tests/data/test-diff-dwarf/test8-report.txt: Likewise. * tests/data/test-diff-dwarf/test9-report.txt: Likewise. * tests/data/test-diff-filter/test13-report.txt: Likewise. * tests/data/test-diff-filter/test6-report.txt: Likewise. * tests/data/test-diff-suppr/test9-changed-parm-c-report-0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * 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>
2015-05-24 15:16:41 +00:00
<pointer-type-def type-id='type-id-8' size-in-bits='64' id='type-id-9'/>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
<namespace-decl name='a'>
Type read from DWARF don't have alignment information Types read from DWARF don't have any alignment information so we shouldn't try to guess it, especially for structures. So this patch sets the alignment to zero in that case. This helps remove some spurious alignment changes detected by abidiff just because in some cases we fail to guess that. In the process, I noticed that when calculating the hash value of a given data member, we were not including the hash value of its context. This led to mistakenly considering some data member changes as redundant. So the patch fixes that too. * src/abg-dwarf-reader.cc (build_type_decl) (build_class_type_and_add_to_ir, build_pointer_type_def) (build_reference_type, build_function_decl): Set the alignment for native types, class, reference and function type to zero, effectively meaning that they don't have alignment information. * src/abg-hash.cc (var_decl::hash::operator): Take the hash value of the data member context in account when computing the hash value of a given data member. * tests/data/test-diff-dwarf/test-23-diff-arch-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test10-report.txt: Likewise. * tests/data/test-diff-dwarf/test13-report.txt: Likewise. * tests/data/test-diff-dwarf/test22-changed-parm-c-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: Likewise. * tests/data/test-diff-dwarf/test8-report.txt: Likewise. * tests/data/test-diff-dwarf/test9-report.txt: Likewise. * tests/data/test-diff-filter/test13-report.txt: Likewise. * tests/data/test-diff-filter/test6-report.txt: Likewise. * tests/data/test-diff-suppr/test9-changed-parm-c-report-0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * 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>
2015-05-24 15:16:41 +00:00
<function-decl name='build_second_type' mangled-name='_ZN1a17build_second_typeEv' filepath='/home/dodji/git/libabigail/dwarf/tests/data/test-read-dwarf/test2-1.cc' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN1a17build_second_typeEv'>
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
<return type-id='type-id-9'/>
Initial support for DW_TAG_partial_unit * src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member. (read_context::read_context): Initialize the new member. (read_context::cur_tu_die): New accessors. (find_last_import_unit_point_before_die): New static function. (get_parent_die): Take a logical current die offset parameter. If the die we want the parent for is a partial unit, then find the last DW_TAG_imported_unit that imports that partial unit before the logical current die and return the parent of that DW_TAG_imported_unit die. (get_scope_for_die): Take a logical current die offset parameter. Adjust. (build_translation_unit_and_add_to_ir): Set/unset the current translation unit DIE in the context. Adjust. (build_namespace_decl_and_add_to_ir) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_typedef_type) (build_var_decl, build_function_decl, build_ir_node_from_die): Take a logical current die offset parameter. Adjust. (build_corpus): Accept that we can have DIE that are not DW_TAG_compile_unit at the top level, because, well, we can now have DW_TAG_partial_unit too. * tests/data/test-read-dwarf/test2-{0,1}.cc: New test source files. * tests/data/test-read-dwarf/test2.h: Likewise. * tests/data/test-read-dwarf/test2.so: New input binary to read. * tests/data/test-read-dwarf/test2.so.abi: New reference test to compare against. * tests/test-read-dwarf.cc: Adjust to launch the new test. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
</function-decl>
</namespace-decl>
</abi-instr>
</abi-corpus>