summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* dwarf-reader: Avoid long comparisons when resolving C++ decl-only classesHEADmasterDodji Seketeli23 hours5-5497/+4187
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When resolving decl-only classes, it can happen that a decl-only class has several candidate classes definitions (in the same binary) to resolve to. In that case, read_context::resolve_declaration_only_classes compares the classes definitions (of the same name) against each other. The problem however is that at that point, we haven't done type canonicalization yet. So comparing these types can have a quadratic behaviour, i.e, take forever, especially in C++. So, if we are looking at C++ (or any language where the ODR rules) types, we can just do away with this comparison and assume the types are equal, as they have the same name. After canonicalization (which comes later), ODR violations can still be detected (if we ware about that at all) anyway. This patch does away with comparing aggregate types (struct/classes) for languages that support the ODR. In so doing, it avoids taking forever while loading the ABI corpus for the libdyninstAPI.so.12 library from Fedora 36. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes): Don't compare same-name-types of a binary if the ODR is relevant. * tests/data/test-annotate/test14-pr18893.so.abi: Adjust. * tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* test-alt-dwarf: Add missing dwz alt-debug fileDodji Seketeli5 days4-0/+10
| | | | | | | | | | | | | | | | It seems I forgot to add a dwz alt-debug file to the test material included in the previous commit. Fixed thus. * tests/data/test-alt-dwarf-file/libstdc++/libstdc++-report-1.txt: New reference test output. * tests/data/test-alt-dwarf-file/libstdc++/usr/lib/debug/.dwz/gcc-12.1.1-1.fc37.x86_64: New dwz alt-debug info file. * tests/data/Makefile.am: Add the test material above to source distribution. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* ir: Make canonicalization stable wrt typedefs in fn return typesDodji Seketeli5 days16-13127/+13134
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the grand scheme of things, two function return types can be equal modulo typedefs. Because those two function textual representations are different, the two overall function types would end up having different canonical types and thus, the two functions would be considered as having different sub-types. The harmless change pass would then kick in and flag that change as harmless. But then, "abidw --abidiff" that is used for testing purposes would still be not happy. This patch strips typedefs off of return types of function types when the string representation is to be used for internal (e.g, type canonicalization) purposes. The fix for this change uncovered another issue: When setting the naming typedefs for an (anonymous) C++ class, the qualified name of the class was wrongly being set to the qualified name of the typedef. Only the name of the class should be affected, in essence. The qualified name would, ONLY as a result of the name change, be adjusted. This patch fixes those issues and adjusts the test suite accordingly. * src/abg-ir.cc (get_function_type_name, get_method_type_name): When the function type name is for internal purposes, strip potential typedefs off. (equal): In the overload for function_type, strip potential typedefs off of return types before comparing them. (decl_base::set_naming_typedef): Properly adjust the qualified name of the type to which a naming typedef is being set. * tests/data/test-alt-dwarf-file/libstdc++/libstdc++-report.txt: New reference test output. * tests/data/test-alt-dwarf-file/libstdc++/usr/lib/debug/usr/lib64/libstdc++.so.6.0.30-12.1.1-1.fc37.x86_64.debug: New binary test input. * tests/data/test-alt-dwarf-file/libstdc++/usr/lib64/libstdc++.so.6.0.30: New binary test input. * tests/data/Makefile.am: Add the new test material to source distribution. * tests/data/test-annotate/test15-pr18892.so.abi: Adjust. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise. * tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise. * tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Update year in copyright noticeDodji Seketeli7 days98-100/+100
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * include/abg-comp-filter.h: Update year in copyright notice. * include/abg-comparison.h: Likewise. * include/abg-config.h: Likewise. * include/abg-corpus.h: Likewise. * include/abg-ctf-reader.h: Likewise. * include/abg-cxx-compat.h: Likewise. * include/abg-diff-utils.h: Likewise. * include/abg-dwarf-reader.h: Likewise. * include/abg-elf-reader-common.h: Likewise. * include/abg-fwd.h: Likewise. * include/abg-hash.h: Likewise. * include/abg-ini.h: Likewise. * include/abg-interned-str.h: Likewise. * include/abg-ir.h: Likewise. * include/abg-libxml-utils.h: Likewise. * include/abg-reader.h: Likewise. * include/abg-regex.h: Likewise. * include/abg-reporter.h: Likewise. * include/abg-sptr-utils.h: Likewise. * include/abg-suppression.h: Likewise. * include/abg-tools-utils.h: Likewise. * include/abg-traverse.h: Likewise. * include/abg-viz-common.h: Likewise. * include/abg-viz-dot.h: Likewise. * include/abg-viz-svg.h: Likewise. * include/abg-workers.h: Likewise. * include/abg-writer.h: Likewise. * src/abg-comp-filter.cc: Likewise. * src/abg-comparison-priv.h: Likewise. * src/abg-comparison.cc: Likewise. * src/abg-config.cc: Likewise. * src/abg-corpus-priv.h: Likewise. * src/abg-corpus.cc: Likewise. * src/abg-ctf-reader.cc: Likewise. * src/abg-default-reporter.cc: Likewise. * src/abg-diff-utils.cc: Likewise. * src/abg-dwarf-reader.cc: Likewise. * src/abg-elf-helpers.cc: Likewise. * src/abg-elf-helpers.h: Likewise. * src/abg-elf-reader-common.cc: Likewise. * src/abg-hash.cc: Likewise. * src/abg-ini.cc: Likewise. * src/abg-internal.h: Likewise. * src/abg-ir-priv.h: Likewise. * src/abg-ir.cc: Likewise. * src/abg-leaf-reporter.cc: Likewise. * src/abg-libxml-utils.cc: Likewise. * src/abg-reader.cc: Likewise. * src/abg-regex.cc: Likewise. * src/abg-reporter-priv.cc: Likewise. * src/abg-reporter-priv.h: Likewise. * src/abg-suppression-priv.h: Likewise. * src/abg-suppression.cc: Likewise. * src/abg-symtab-reader.cc: Likewise. * src/abg-symtab-reader.h: Likewise. * src/abg-tools-utils.cc: Likewise. * src/abg-traverse.cc: Likewise. * src/abg-viz-common.cc: Likewise. * src/abg-viz-dot.cc: Likewise. * src/abg-viz-svg.cc: Likewise. * src/abg-workers.cc: Likewise. * src/abg-writer.cc: Likewise. * tests/print-diff-tree.cc: Likewise. * tests/test-abicompat.cc: Likewise. * tests/test-abidiff-exit.cc: Likewise. * tests/test-abidiff.cc: Likewise. * tests/test-alt-dwarf-file.cc: Likewise. * tests/test-core-diff.cc: Likewise. * tests/test-cxx-compat.cc: Likewise. * tests/test-diff-dwarf-abixml.cc: Likewise. * tests/test-diff-dwarf.cc: Likewise. * tests/test-diff-filter.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tests/test-diff2.cc: Likewise. * tests/test-elf-helpers.cc: Likewise. * tests/test-ini.cc: Likewise. * tests/test-ir-walker.cc: Likewise. * tests/test-kmi-whitelist.cc: Likewise. * tests/test-lookup-syms.cc: Likewise. * tests/test-read-ctf.cc: Likewise. * tests/test-read-dwarf.cc: Likewise. * tests/test-read-write.cc: Likewise. * tests/test-symtab-reader.cc: Likewise. * tests/test-symtab.cc: Likewise. * tests/test-tools-utils.cc: Likewise. * tests/test-types-stability.cc: Likewise. * tests/test-utils.cc: Likewise. * tests/test-utils.h: Likewise. * tools/abicompat.cc: Likewise. * tools/abidiff.cc: Likewise. * tools/abidw.cc: Likewise. * tools/abilint.cc: Likewise. * tools/abipkgdiff.cc: Likewise. * tools/abisym.cc: Likewise. * tools/binilint.cc: Likewise. * tools/kmidiff.cc: Likewise. * update-copyright.sh: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* reporter-priv: Passing a string parm by referenceDodji Seketeli7 days2-3/+2
| | | | | | | | | | | | | While looking at something else, I noticed the maybe_report_data_members_replaced_by_anon_dm function was passing a string parameter by value. Pass this by reference. * src/abg-reporter-priv.h (maybe_report_data_members_replaced_by_anon_dm): Pass the string parm by ... * src/abg-reporter-priv.cc (maybe_report_data_members_replaced_by_anon_dm): ... reference. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* dwarf-reader: Fix DWARF string comparison optimizationDodji Seketeli8 days10-19851/+19844
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fix has been triggered by a fix posted by Thomas Schwinge in the thread that started at https://sourceware.org/pipermail/libabigail/2022q1/004139.html. Thomas rightfully notes that compare_dies_string_attribute_value is wrong. In some cases, it wrongly considers only the first character of the two strings to compare. This patch fixes that and updates the regression tests accordingly. The fix suppresses several spurious changes (in runtestdifffilter) that were there and I never got the bottom of them. Now they are gone. * src/abg-dwarf-reader.cc (slowly_compare_strings) (die_char_str_attribute): Define new static functions. (compare_dies_string_attribute_value): Use the new slowly_compare_strings here. * tests/data/test-annotate/test15-pr18892.so.abi: Adjust. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi: Likewise. * tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Canonicalize DIEs w/o assuming ODR & handle typedefs transparentlyDodji Seketeli8 days95-179241/+259967
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When canonicalizing DIEs, if two type DIEs have the same textual representation and we are looking at a C++ DIE, then we assume the two DIEs are equivalent because of the "One Definition Rule" of C++. There are binaries however where there seem to be type DIEs that are slightly different and yet with the same textual representation. It seems that this leads to some heisenbugs depending on which of the two DIEs is "kept". That order would then depend on whatever the linker's output is at a particular moment when linking the binary. Those slight differences (i.e, modulo typedefs, for instance) are a pain to reproduce across binaries that are re-linked. So I am removing this optimization. As it doesn't seem to be so useful anymore, given all the areas of the pipeline that go improved recently, speed-wise. After doing that, it appeared the comparison engine was seeing more DIE kinds. So rather than aborting when seeing an unexpected DIE kind, we now assume the two DIEs we are seeing are different. They are thus not canonicalized. That's not a problem because the IR level type canonicalizer will pick that up and fully canonicalize the type at that level. So as that is in place, it appeared we were doing canonical DIE propagation even in cases where we should not. Namely, when a subset of the stack of aggregates being compared depends on a recursive (or redundant) sub-type, no canonical type DIE propagation should be performed. The patch thus detects that state of things and disables the canonical type DIE propagation in that case. Once this change in place, as the DIE canonicalizer started to look into more types, the IR started to get more types that were deemed equal to their decl-only counterpart before, and so were represented those decl-only counterpart by virtue of the ODR. That uncovered the long standing issue described below. Canonicalizing typedefs is done today by considering that two typedefs that have different names are different even if they have the same underlying types. That means we can have two types T and T' (in a binary) that are equivalent modulo a sub-type that is a typedef with different names in T and T', yet with equivalent underlying types. Today, libabigail would consider T and T' different, even though they are equivalent from an ABI standpoint. This can lead to spurious changes that we have to handle later by adding passes that would suppress those spurious changes. This patch thus changes the structural comparison for typedefs by not taking the typedef name into account anymore. Also, typedefs don't carry canonical types anymore. That way, to compare typedefs, libabigail always look into their underlying types. To adapt the precision of the abixml output, the patch now uses a special set (to track emitted non-canonicalized types) and a special map (to track type ID for non-canonicalized types) as those can't be put in the classical maps that track types using their canonical types. * include/abg-fwd.h (peel_typedef_pointer_or_reference_type): Declare new function. * src/abg-dwarf-reader.cc (read_context::{compute_canonical_die, get_canonical_die, get_or_compute_canonical_die}): Don't special-case ODR-relevant cases. (is_canon_type_to_be_propagated_tag): Rename is_canonicalizeable_type_tag into this. (erase_offset_pair): Make this return a bool, not void. (have_offset_pair_in_common, try_canonical_die_comparison) (notify_die_comparison_failed): Define new static functions. (ABG_RETURN, ABG_RETURN_FALSE): Define new macros. (compare_dies): Handle DW_TAG_{class,unspecified}_type DIES. Also if a comparing a DIE kind is not supported, assume the comparison yields "false" for the purpose of canonicalization. Add a new parameter for redundant aggregates being compared. Use the redundant aggregate set to detect if a redundant aggregate has been detected and is still being "explored"; if that's the case, then canonical DIE propagation is de-activated. This might incur a performance hit. Use the new ABG_RETURN and ABG_RETURN_FALSE macros. Use the new try_canonical_die_comparison to compare canonical DIEs rather than doing it by hand. (build_typedef_type): Don't try to rely on canonical typedefs DIEs. * src/abg-ir.cc (type_topo_comp::has_artificial_or_natural_location): Define new method. (type_topo_comp::operator(const type_base*, const type_base*)): In this topological comparison operator of types, when two types have the same textual representation, if they don't have any location, if they are pointer/reference/typedef types, use the textual representation of their ultimate underlying type for sorting order. (peel_typedef_pointer_or_reference_type): Define new function. (compare_types_during_canonicalization): Perform the structural canonical comparison first. (equals): In the overload for array_type_def::subrange_type&, remove unused code. In the overload for typedef_decl& don't compare typedef names. In the overload for class_or_union, make the RETURN macro *NOT* propagate canonical type because this equal function is used as a subroutine by overloads for class and union. That means that the class_or_union equal function can return true, and still, the caller (overload for class_decl or union_decl) can later return false; in that case, we don't want canonical type to be propagated. In the overload for class_decl::base_spec, use the ABG_RETURN macro when returning comparing decl-bases. In the overload for class_decl, use ABG_RETURN when returning the result of comparing class_or_union artifacts. (maybe_propagate_canonical_type): If we are using canonical type comparison, then do not propagate the type, if WITH_DEBUG_TYPE_CANONICALIZATION is defined. (is_non_canonicalized_type): Add typedefs to the set of non-canonicalized types. * src/abg-writer.cc (struct non_canonicalized_type_hash, struct non_canonicalized_type_equal): Define new functors. (typedef nc_type_ptr_set_type): Define a new non-canonicalized set type. (typedef nc_type_ptr_istr_map_type): Define a new map of non-canonicalized types/interned string map. (write_context::{m_nc_type_id_map, m_emitted_non_canonicalized_type_set, m_referenced_non_canonicalized_types_set}): New data members. (write_context::type_has_existing_id): Look for non-canonicalized types in the m_nc_type_id_map map. (write_context::get_id_for_type): Use m_nc_type_id_map for non-canonicalized types. (write_context::clear_type_id_map): Clear m_nc_type_id_map too. (write_context::get_referenced_non_canonicalized_types): Renamed write_context::get_referenced_non_canonical_types into this. Make it return the new write_context::m_referenced_non_canonicalized_types_set. (write_context::has_non_emitted_referenced_types): Just use write_context::type_is_emitted as it knows where to look up for non-canonicalized types. (write_context::record_type_as_referenced): Use m_referenced_non_canonicalized_types_set to store referenced non-canonicalized types. The other types are stored in m_emitted_set as previously. (write_context::type_is_emitted): Look into m_emitted_non_canonicalized_type_set for non-canonicalized types. Other types are still in m_emitted_type_set. (write_context::{record_decl_only_type_as_emitted, decl_only_type_is_emitted, get_emitted_decl_only_types_set}): Remove methods. (write_context::get_emitted_non_canonicalized_type_set): Define new method. (write_context::clear_referenced_types): Clear m_referenced_non_canonicalized_types_set too, as m_referenced_non_canonical_types_set is no more. (write_context::referenced_type_should_be_emitted): Use only write_context::type_is_emitted as it knows how to check it all now. (write_referenced_types): Use the more compact ranged-base for loops. (write_translation_unit): Write the non-canonicalized types that are not yet emitted. (write_class_decl, write_union_decl): Adjust recording type as emitted. (write_canonical_type_ids): Adjust. * tests/data/test-abidiff/test-PR18791-report0.txt: Adjust. * tests/data/test-annotate/libtest23.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test-anonymous-members-0.o.abi: Likewise. * tests/data/test-annotate/test0.abi: Likewise. * tests/data/test-annotate/test1.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Adjust. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test2.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-annotate/test3.so.abi: Likewise. * tests/data/test-annotate/test5.o.abi: Likewise. * tests/data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi: Likewise. * tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi: Likewise. * tests/data/test-diff-dwarf/PR25058-liblttng-ctl-report-1.txt: Likewise. * tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test41-report-0.txt: Likewise. * tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64: Likewise. * tests/data/test-diff-pkg/nmap-7.70-5.el8_testjcc.x86_64-self-check-report-0.txt: Likewise * tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-0.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. * tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Likewise. * tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt: Likewise. * tests/data/test-diff-suppr/test39-opaque-type-report-0.txt: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-functions-declaration.abi: Likewise. * tests/data/test-read-ctf/test1.so.abi: Likewise. * tests/data/test-read-ctf/test1.so.hash.abi: Likewise. * tests/data/test-read-ctf/test2.so.abi: Likewise. * tests/data/test-read-ctf/test2.so.hash.abi: Likewise. * tests/data/test-read-ctf/test5.o.abi: Likewise. * tests/data/test-read-ctf/test7.o.abi: Likewise. * tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Likewise. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise. * tests/data/test-read-dwarf/PR24378-fn-is-not-scope.abi: Likewise. * tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise. * tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi: Likewise. * tests/data/test-read-dwarf/PR26261/PR26261-exe.abi: Likewise. * tests/data/test-read-dwarf/PR27700/test-PR27700.abi: Likewise. * tests/data/test-read-dwarf/libtest23.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test-PR26568-1.o.abi: Likewise. * tests/data/test-read-dwarf/test-PR26568-2.o.abi: Likewise. * tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise. * tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise. * tests/data/test-read-dwarf/test-suppressed-alias.o.abi: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * tests/data/test-read-dwarf/test0.hash.abi: Likewise. * tests/data/test-read-dwarf/test1.abi: Likewise. * tests/data/test-read-dwarf/test1.hash.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test2.so.abi: Likewise. * tests/data/test-read-dwarf/test2.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test3-alias-1.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test3-alias-2.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test3-alias-3.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test3-alias-4.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test3.so.abi: Likewise. * tests/data/test-read-dwarf/test3.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test5.o.abi: Likewise. * tests/data/test-read-dwarf/test5.o.hash.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. * tests/data/test-read-write/test18.xml: Likewise. * tests/data/test-read-write/test28-without-std-fns-ref.xml: Likewise. * tests/data/test-read-write/test28-without-std-vars-ref.xml: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* dwarf-reader: compare_dies sometimes compares empty formal parmsDodji Seketeli8 days1-3/+4
| | | | | | | | | | compare_dies sometimes compares uninitialized DIE structs, which leads to junk down the road. Fixed thus. * src/abg-dwarf-reader.cc (compare_dies): Don't try to compare formal parameters if there is none. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* abidw, dwarf-reader: Add an option to debug DIE canonicalizationDodji Seketeli8 days5-6/+132
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | While looking at something else, it appeared that I needed an option to turn on checks to debug DIE canonicalization. That option would itself be enable only when the project is configured using the --enable-debug-type-canonicalization configure option. * include/abg-ir.h (environment::debug_die_canonicalization_is_on): Declare new methods. * src/abg-ir.cc (environment::debug_die_canonicalization_is_on): Define them. * src/abg-dwarf-reader.cc (compare_dies_during_canonicalization): Define new static function. (read_context::{debug_die_canonicalization_is_on_, use_canonical_die_comparison_}): Declare these data members. (read_context::read_context): Initialize them. (read_context::get_canonical_die): When ODR is considered, if DIE canonicalization debugging is on, use the new compare_dies_during_canonicalization for the type comparison to be done both structurally and canonically; both comparison should yield the same result. Also, make this method function non-const. * src/abg-ir-priv.h (environment::priv::debug_die_canonicalization_): Define new data member. (environment::priv::priv): Initialize it. * tools/abidw.cc (options::debug_die_canonicalization_): Define new data member. (options::options): Initialize it. (display_usage): Add a description for the --debug-dc option. (parse_command): Parse the new --debug-dc option. (load_corpus_and_write_abixml): Use the new environment::debug_die_canonicalization_is_on. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* test-read-dwarf: Use abidw rather than using the libraryDodji Seketeli8 days53-543/+490
| | | | | | | | | | | | | | | | | | When this test fails, sometimes it's difficult to reproduce the problem using abidw. That's because this test is using the library directly, so the exact setup is not always straightforward to reproduce and eventually debug. This test changes tests/test-read-dwarf.cc to make it use abidw rather than using the library directly. * tests/test-read-dwarf.cc (set_suppressions) (set_suppressions_from_headers): Remove these static functions. (test_task_dwarf::perform): Use abidw rather than using the library. Remove the path and architecture from the abixml files. Also, when the test fails, display the actual command that failed. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Add better error messaging to several testsDodji Seketeli8 days3-3/+12
| | | | | | | | | | | | | When test-read-dwarf and test-diff-filter fail, it's important to know what exact command line failed. This patch makes these tests display the failing command. * tests/test-diff-filter.cc (test_task::perform): Display the failing command. * tests/test-read-common.cc (test_task::run_abidw): Likewise. * tests/test-read-common.h (test_task::run_diff): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* ir, test-read-ctf: Remove uncertainty in sorting anonymous typesDodji Seketeli2022-06-135-32/+32
| | | | | | | | | | | | | | | | | | | | | | For a reason, I am seeing changes in the test-read-ctf output. Those are related to sorting anonymous structs that have no (internal) name. The CTF reader emits such types. This patch thus considers the flat representation of an anonymous class/union when it doesn't have an internal name. The patch also updates the test-read-ctf output tests accordingly. * src/abg-ir.cc ({class_decl, union_decl}::get_pretty_representation): If the anonymous class has no internal name, use its flat representation as internal representation. * tests/data/test-read-ctf/test-PR26568-1.o.abi: Likewise. * tests/data/test-read-ctf/test-PR26568-2.o.abi: Likewise. * tests/data/test-read-ctf/test-anonymous-fields.o.abi: Likewise. * tests/data/test-read-ctf/test-anonymous-fields.o.abi: Likewise. * tests/data/test-read-ctf/test0.hash.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* limit repeated DIE comparisonsGiuliano Procida2022-06-091-0/+12
| | | | | | | | | | | | | | | | | | | Exponential explosion of DIE comparison has been possible since the limit of at most 5 pending struct/union DIE comparison pairs was lifted. This commit adds two things to control this (with a negligible chance of falsely finding that two DIEs are equivalent when they are not). - DIE self-comparisons immediately return true - once a DIE pair has been compared 10000 times, always return true * src/abg-dwarf-reader.cc (read_context): Add mutable die_comparison_visits_ member. (compare_dies): Return true if this is a self-comparison. Return true if we have visited this comparison 10000 times. Signed-off-by: Giuliano Procida <gprocida@google.com>
* abicompat: Properly guard inclusion of abg-ctf-reader.hDodji Seketeli2022-06-091-1/+3
| | | | | | | | | | | A recent patch to add CTF support to abicompat included abg-ctf-reader.h without guarding it with #ifdef WITH_CTF. This patch fixes that. * tools/abicompat.cc: Guard inclusion of abg-ctf-reader.h with #ifdef WITH_CTF. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Bug 29144 - abidiff doesn't report base class re-orderingDodji Seketeli2022-06-0815-5/+162
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Libabigail fails to report when a base class gets re-ordered, even though the comparison engine detects the change. This patch detects the base class re-ordering in class_diff::ensure_lookup_tables_populated by interpreting the edit script resulting of the comparison, populates a new class_diff::priv::moved_bases_ vector with the bases that "changed position" and adds a new class_diff::moved_bases() accessor for the "base classes that changed position". A new function maybe_report_base_class_reordering is defined to actually report a base class re-ordering if class_diff::moved_bases() returns a non-empty vector, meaning that class has some base classes that got re-ordered. That new function is thus called in the overload of {default_reporter, leaf_reporter}::report() for class_diff to emit a description of the change when necessary. * include/abg-comparison.h (class_diff::moved_bases): Declare new method. * src/abg-comparison-priv.h (class_diff::priv::moved_bases_): Define new data member. * src/abg-reporter-priv.h (maybe_report_base_class_reordering): Declare new function. * src/abg-reporter-priv.cc (maybe_report_base_class_reordering): Define new function. * src/abg-comparison.cc (class_diff::ensure_lookup_tables_populated): Detect that a base class moved position and record it into class_diff::priv::moved_bases_ data member. * src/abg-default-reporter.cc (default_reporter::report): Use the new maybe_report_base_class_reordering. * src/abg-leaf-reporter.cc (leaf_reporter::report): Likewise. * tests/data/test-abidiff-exit/test-PR29144-report-2.txt: New testing input file. * tests/data/test-abidiff-exit/test-PR29144-report.txt: Likewise. * tests/data/test-abidiff-exit/test-PR29144-v0.cc: Likewise. * tests/data/test-abidiff-exit/test-PR29144-v0.o: Likewise. * tests/data/test-abidiff-exit/test-PR29144-v1.cc: Likewise. * tests/data/test-abidiff-exit/test-PR29144-v1.o: Likewise. * tests/data/Makefile.am: Add the new files to source distribution. * tests/test-abidiff-exit.cc (in_out_specs): Add the new tests to this harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* abicompat: Support reading CTF and abixmlBen Woodard via Libabigail2022-06-082-33/+151
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | While abidw generates abidw and abidiff can consume that abidw abicompat could only read from ELF objects with DWARF. To bring it in line with the capabilities of abidiff, this patch adds the ability for abicompat to read both abixml and CTF. The reason why being able to handle abixml as well as an ELF file with DWARF is that it allows someone to archive the abixml for an object and use it in place of having to keep the entire object when doing abi compatibility studies. The ability to handle CTF was also in the code that I copied over from abidiff and so I brought it over at the same time. This should be tested more extensively. The make check works and a trivial test using the same object seems to work but I do not have any CTF other binaries around to test against. Also a feature that I asked for a long time ago was to fail if the binaries don't have debug infomation which is needed for proper comparison. This was added to abidiff but it didn't get added to abicompat. Since the code was in the same area, I copied it over from abidiff at the same time. I do not think it makes sense to try to split these three features apart because they are just replicating pre-existing code in a different tool. * tools/abicompat.cc (options::{fail_no_debug_info, use_ctf}): New data members. (options::options): Initialize them. (display_usage): Add a help string for the new options --fail-no-debug-info and --ctf. (parse_command_line): Support parsing the new options --fail-no-debug-info and --ctf. (read_corpus): New static function. (main): Use the new read_corpus in lieu of using dwarf_reader::read_corpus_from_elf and/or ctf_reader::read_corpus and/or xml::reader::read_corpus_from_input. * doc/manuals/abicompat.rst: add documentation for new options. Signed-off-by: Ben Woodard <woodard@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* abidiff: Remove redundant codeBen Woodard2022-06-071-13/+0
| | | | | | | | | | | While working on abicompat, I noticed that the following two blocks of code are redundant. They perform the same test as in the switch statement a few lines below. * tools/abidiff.cc (main): Remove redundant code. Signed-off-by: Ben Woodard <woodard@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* XML writer: unify type emission trackingGiuliano Procida2022-06-071-82/+8
| | | | | | | | | | | | | | | | | | | | | | | Empirically, the tracking of declaration-only type emission no longer seems to make any difference. It is removed here. * src/abg-writer.cc (write_context): Remove the m_emitted_decl_only_set member. (write_context::has_non_emitted_referenced_types): Remove the calls to decl_only_type_is_emitted. (write_context::record_decl_only_type_as_emitted): Removed. (write_context::decl_only_type_is_emitted): Ditto. (write_context::get_emitted_decl_only_types_set): Ditto. (referenced_type_should_be_emitted): Remove the calls to decl_only_type_is_emitted. (write_class_decl): Just call record_type_as_emitted. (write_union_decl): Ditto. (write_enum_type_decl): Not changed, but now all 3 functions have the same behaviour. (write_canonical_type_ids): Remove the call to get_emitted_decl_only_types_set. Signed-off-by: Giuliano Procida <gprocida@google.com>
* abicompat: Add missing spaceBen Woodard2022-06-071-1/+1
| | | | | | | | | | This is absolutely trivial but I noticed this missing space one day and fixed it and have been carrying the hunk of patch for months. * tools/abicompat.cc (main): Add missing space in expression. Signed-off-by: Ben Woodard <woodard@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* comparison: Fix leaf report summaryDodji Seketeli2022-06-021-1/+5
| | | | | | | | | | | | | | | This patch is to address the problem reported at https://sourceware.org/bugzilla/show_bug.cgi?id=29047 where the leaf changes summary omits the number of (added/removed) ELF symbols that have no debug info. Fixed thus. * src/abg-comparison.cc (corpus_diff::priv::emit_diff_stats): In the "leaf change summary" section, add the number of removed/added symbols not described by debug info. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* test-annotate.cc: ignore whitespace during diffGiuliano Procida2022-05-301-1/+1
| | | | | | | | | | | | The LLVM C++ demangler is being updated to remove the extra space delimiter added between consecutive template closings. This change ensures tests pass with both old and new versions. * tests/test-annotate.cc (main): Pass diff -w option. Suggested-by: Bogdan Graur <bgraur@google.com> Signed-off-by: Giuliano Procida <gprocida@google.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* symtab-reader: Setup aliases before checking ppc64 opd function entriesMark Wielaard2022-05-304-31/+53
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The update_function_entry_address_symbol_map function checks whether the given symbol is an alias of another symbol or a special ppc64 ELFv1 function entry symbol. This requires the symbol aliases to already been setup. But the alias entries were only setup after calling update_function_entry_address_symbol_map. Make sure that the symbol aliases have been setup and only then call the special ppc64 update_function_entry_address_symbol_map function. But make sure the arm32 function symbol entry address cleanup is done before checking for aliases. This patch renames symtab::get_symbol_value into symtab::setup_symbol_lookup_tables to better reflect what it does. It is in that function that the call to update_function_entry_address_symbol_map is performed, the arm32 symbol address cleanup is done and the ppc64 ELFv1 function address plumbing is done. So arranging for update_function_entry_address_symbol_map to be called after symbol aliases are setup for ppc64 is also done in that function. That way, symtab::load_ only have to call symtab::setup_symbol_lookup_tables to have aliases setup. This fixes runtestslowselfcompare.sh on ppc64 (ELFv1) with ENABLE_SLOW_TEST=yes * src/abg-elf-helpers.h (architecture_is_ppc32): Declare new function. * src/abg-elf-helpers.cc (architecture_is_ppc32): Define it. * src/abg-symtab-reader.cc (symtab::setup_symbol_lookup_tables): Rename symtab::get_symbol_value into this. Setup symbol aliases before setting up function entry address maps for ppc{32,64} ELFv1 and after fixing up arm32/64 addresses. (symtab::load_): Invoke the new setup_symbol_lookup_tables. update_function_entry_address_symbol_map after setting up aliases. No need to setup symbol aliases anymore. (symtab::add_alternative_address_lookups): Invoke the new setup_symbol_lookup_tables. Signed-off-by: Mark Wielaard <mark@klomp.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* ctf-reader: add support to looking debug information in external pathGuillermo E. Martinez2022-05-179-48/+168
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When an ELF `stripped' file is used to get CTF debug information the ELF symbols used by ctf reader (`symtab_reader::symtab') is split in a separate file and even though CTF was designed to be in ELF file after be `stripped' this .ctf section can be 'loaded' from and external .debug file, for instance the script `find-debuginfo' used to generate RPM debug packages split debug information in .debug files. The location of such files is pass as a standard argument from libabigail tools and the name of the file is gathering from the `.gnu_debuglink' section. * include/abg-ctf-reader.h (ctf_reader::create_read_context): Add `debug_info_root_paths' argument. (ctf_reader::reset_read_context): Likewise. * src/abg-ctf-reader.cc: Add `read_context::elf_{handler,fd}_dbg', data members. (read_context::read_context): Add new `debug_info_root_paths' argument. (read_context::initialize): Likewise. (ctf_reader::create_read_context): Likewise. (ctf_reader::close_elf_handler): Release `read_context::elf_{handler,fd}_dbg' members. (ctf_reader::find_alt_debuginfo): Add new function. (ctf_reader::slurp_elf_info): Add new argument `status'. Use `find_alt_debuginfo' and `elf_helpers::find_section_by_name' to read the symtab and ctf information from an external .debug file, the `status' reference is updated. (ctf_reader::read_corpus): Verify `status' after `slurp_elf_info'. (ctf_reader::reset_read_context): Add new `debug_info_root_path' argument. * src/abg-elf-helpers.cc (elf_helpers::find_section_by_name): Update comment. * src/abg-tools-utils.cc (maybe_load_vmlinux_ctf_corpus): Adjust `ctf_reader::{create,reset}_read_context'. * tests/test-read-ctf.cc: Likewise. * tools/abidiff.cc (display_usage): Add `--ctf' command line option. (main): Adjust `ctf_reader::create_read_context'. Likewise. * tools/abidw.cc (load_corpus_and_write_abixml): Adjust `ctf_reader::create_read_context'. * tools/abilint.cc (main): Likewise. * tools/abipkgdiff.cc (compare, compare_to_self): Likewise. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Adding missing newline to build-container workflowVanessa Sochat2022-05-171-1/+2
| | | | | | | | | | Adding missing newline to build-container workflow. * .github/workflows/build-container.yaml: Add missing newline. Signed-off-by: Vanessa Sochat <sochat1@llnl.gov> Reviewed-by: Ben Woodard <woodard@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Add github actions to support workflowsBen Woodard2022-05-1710-0/+514
| | | | | | | | | | | | | | | | | | | | | | | | | | To facilitate collaboration with developers working on the BUILD-SI project who are using github, I have been maintaining a clone of the libabigail repo there. Having this repo also allows us to leverage some of the tooling that github provides, in particular the ability to have github actions test patches to verify that the builds succeed, and all the regression tests run successfully. This will allow it to better integrate with the normal agile workflow used by at least this community of developers. * .github/workflows/build-container.yaml: New file. * .github/workflows/libabigail.yaml: Likewise. * .github/workflows/test.yaml: Likewise. * .github/workflows/test-fedora.yaml: Likewise. * .github/README.md: Likewise. * docker/Dockerfile.fedora: Likewise. * docker/Dockerfile.ubuntu: Likewise. * docker/Dockerfile.fedora-base: Likewise. * docker/Dockerfile.test: Likewise. * README-DOCKER.md: Likewise. Signed-off-by: Vanessa Sochat <sochat1@llnl.gov> Reviewed-by: Ben Woodard <woodard@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* abipkgdiff: Add support to compare packages with CTF debug formatGuillermo E. Martinez2022-05-162-20/+98
| | | | | | | | | | | | | | | | | This patch add support in `abipkgdiff' to compare binaries with CTF debug information inside of packages, when `--ctf' option is provided. * tools/abipkgdiff.cc: Include `abg-ctf-reader.h'. (options::use_ctf): Add new data member. (display_usage): Add `--ctf' usage. (compare): Add condition to use ctf-reader to extract (parse_command_line): Set `options::use_ctf' when --ctf option is provided. and build CTF corpora when `options::use_ctf' is set. (compare_to_self): Likewise. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* ctf-reader: CTF debug info for some symbols is not foundGuillermo E. Martinez2022-05-133-18/+67
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Running `abidw --ctf' tool for some executable ELF files, seems that ctf reader is unable to get debug information for some symbols so, they will not be neither the corpus nor in abixml file. This is happening because internally the reader uses `ctf_arc_bufopen' expecting as argument the sections: symbol table (.dynsym) and string table (.dynstr) for ELF types: ET_{EXEC,DYN}, currently those sections are read by `elf_helpers' but it uses .symtab when it is present and `symtab_shdr->sh_link' to get .strtab, instead. * src/abg-ctf-reader.cc (read_context::is_elf_exec): Remove data member. (ctf_reader::process_ctf_qualified_type): Add condition to avoid use qualifier in functions. (ctf_reader::process_ctf_archive): Use `ctf_lookup_by_symbol_name' to find debug information when `ctf_lookup_variable' was not lucky iff `corpus::CTF_ORIGIN'. (ctf_reader::slurp_elf_info): Use `elf_helpers::find_section_by_name' to read .dynsym and .dynstr when {EXEC,DYN}. * src/abg-elf-helpers.h (elf_helpers::find_section_by_name): Add new declaration. * src/abg-elf-helpers.cc (elf_helpers::find_section_by_name): Add new definition. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* ctf-reader: shows incomplete summary changesGuillermo E. Martinez2022-05-134-9/+101
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | During corpus comparison with ctf support, summary changes for functions and variables are shown like to the binaries doesn't have ctf debug information, even though they were compiled with '-gctf' compiler modifier, e.g: 2 Removed function symbols not referenced by debug info: [D] elf32_test_main@@ELFUTILS_1.7 [D] elf64_test_main@@ELFUTILS_1.7 So, expected changes summary should be: 2 Removed functions: [D] 'function long int elf32_test_main()' {elf32_test_main@@ELFUTILS_1.7} [D] 'function long int elf64_test_main()' {elf64_test_main@@ELFUTILS_1.7} * src/abg-ctf-reader.cc (read_context::exported_decls_builder_): Add new data member. (read_context::exported_decls_builder): Add new get/set member functions. (read_context::maybe_add_{fn,var}_to_exported_decls): Likewise. (read_context::initialize): Initialize exported_decls_builder_ member. (read_context::build_ir_node_for_variadic_parameter_type): Add new function. (read_context::process_ctf_function_type): Add additional code to handle function's variadic parameter. (read_context::process_ctf_archive): Rename variable for clarity from `ctf_var_type' to `ctf_sym_type', using new member functions `maybe_add_{fn,var}_to_exported_decls'. (read_context::read_corpus): Set `exported_decls_builder'. * tests/test-read-common.cc (test_task::run_abidw): Fix error message. * tests/data/test-read-ctf/test-PR26568-1.o.abi: Adjust test case. * tests/data/test-read-ctf/test-PR26568-2.o.abi: Likewise. * tests/data/test-read-ctf/test-anonymous-fields.o.abi Likewise. * tests/data/test-read-ctf/test5.o.abi: Likewise. * tests/data/test-read-ctf/test7.o.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Fix numbering error in the abidiff manual.Frederic Cambus2022-05-131-1/+1
| | | | | | | * doc/manuals/abidiff.rst: Fix numbering error for the --headers-dir2 option. Signed-off-by: Frederic Cambus <fred@statdns.com>
* ctf-reader: Add support to read CTF information from the Linux KernelGuillermo E. Martinez2022-05-1352-367/+1068
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch is meant to extract ABI information from the CTF data stored in the Linux kernel build directory. It depends on the vmlinux.ctfa archive file. In order to generate the CTF information, the Linux Kernel build system must support the 'make ctf' command, which causes the compiler to be run with -gctf, thus emitting the CTF information for the Kernel. The target 'ctf' in the Linux Makefile generates a 'vmlinux.ctfa' file that will be used by the ctf reader in libabigail. The 'vmlinux.ctfa' archive has multiple 'ctf dictionaries' called "CTF archive members". There is one CTF archive member for built-in kernel modules (in `vmlinux') and one for each out-of-tree kernel module organized in a parent-child hierarchy. There is also a CTF archive member called `shared_ctf' which is a parent dictionary containing shared symbols and CTF types used by more than one kernel object. These common types are stored in 'types_map' in the ctf reader, ignoring the ctf dictionary name. The CTF API has the machinery for looking for a shared type in the parent dictionary referred to in a given child dictionary. This CTF layout can be dumped by using the objdump tool. Due to the fact that the _same_ ctf archive is used to build the vmlinux corpus the corpora of the kernel module (which, by the way, all belong to the same corpus group), the high number of open/close on the CTF archive is very time consuming during the ctf extraction. So, the performance is improved up to 300% (from ~2m:50s to ~50s) by keeping the ctf archive open for a given group, and thus, by using the same ctf_archive_t pointer while building all the various corpora. We just invoke `reset_read_context' for each new corpus. Note that the `read_context::ctfa` data member should be updated if the corpus::origin data member is set to `LINUX_KERNEL_BINARY_ORIGIN' and the file to be process is not 'vmlinux'. Note that `ctf_close' must be called after processing all group's members so it is executed from the destructor of `reader_context'. The basic algorithm used to generate the Linux corpus is the following: 1. Looking for: vmlinux, *.ko objects, and vmlinux.ctfa files. The first files are used to extract the ELF symbols, and the last one contains the CTF type information for non-static variables and functions symbols. 2. `process_ctf_archive' iterates on public symbols for vmlinux and its modules, using the name of the symbol, ctf reader search for CTF information in its dictionary, if the information was found it builds a `var_decl' or `function_decl' depending of `ctf_type_kind' result. This algorithm is also applied to ELF files (exec, dyn, rel), so instead of iterating on all ctf_types it just loops on the public symbols. * abg-elf-reader-common.h: Include ctf-api.h file. (read_and_add_corpus_to_group_from_elf, set_read_context_corpus_group) (reset_read_context, dic_type_key): Declare new member functions. * include/abg-ir.cc (types_defined_same_linux_kernel_corpus_public): Use bitwise to know the corpus `origin'. * src/abg-ctf-reader.cc: Include map, algorithms header files. (read_context::type_map): Change from unordered_map to std::map storing ctf dictionary name as part of the key. (read_context::is_elf_exec): Add new member variable. (read_context::{cur_corpus_, cur_corpus_group_}): Likewise. (read_context::unknown_types_set): Likewise. (read_context::{current_corpus_group, main_corpus_from_current_group, has_corpus_group, current_corpus_is_main_corpus_from_current_group, should_reuse_type_from_corpus_group}): Add new member functions. (read_context::{add_unknown_type, lookup_unknown_type, initialize}): Likewise. (read_context::{add_type, lookup_type}): Add new `ctf_dict_t' type argument. (ctf_reader::{process_ctf_typedef, process_ctf_base_type, process_ctf_function_type, process_ctf_forward_type, process_ctf_struct_type, process_ctf_union_type, process_ctf_array_type, process_ctf_qualified_type, process_ctf_enum_type}): Add code to `reuse' types already registered in main corpus `should_reuse_type_from_corpus_group'. Use new `lookup_type' and `add_type' operations on `read_context::types_map'. Replace function calls to the new ctf interface. Add verifier to not build types duplicated by recursive calling chain. (ctf_reader::process_ctf_type): Add code to return immediately if the ctf type is unknown. Add unknown types to `unknown_types_set'. (ctf_reader::process_ctf_archive): Change comment. Add code to iterate over global symbols, searching by symbol name in the ctf dictionary using `ctf_lookup_{variable,by_symbol_name}' depending of the ELF file type and corpus type, creating a `{var,fuc}_decl' using the return type of `ctf_type_kind'. Also close the ctf dict and call `canonicalize_all_types'. (slurp_elf_info): Set `is_elf_exec' depending of ELF type. Also return success if corpus origin is Linux and symbol table was read. (ctf_reader::read_corpus): Add current corpus. Set corpus origin to `LINUX_KERNEL_BINARY_ORIGIN' if `is_linux_kernel' returns true. Verify the ctf reader status, now the ctf archive is 'opened' using `ctf_arc{open,bufopen}' depending if the corpus origin has `corpus::LINUX_KERNEL_BINARY_ORIGIN' bit set. Use `sort_{function,variables}' calls after extract ctf information. `ctf_close' is called from `read_context' destructor. (read:context::{set_read_context_corpus_group, reset_read_context, read_and_add_corpus_to_group_from_elf, dic_type_key): Add new member function implementation. * include/abg-tools-utils.h (build_corpus_group_from_kernel_dist_under): Add `origin' parameter with default `corpus::DWARF_ORIGIN'. * src/abg-tools-utils.cc: Use `abg-ctf-reader.h' file. (maybe_load_vmlinux_dwarf_corpus): Add new function. (maybe_load_vmlinux_ctf_corpus): Likewise. (build_corpus_group_from_kernel_dist_under): Update comments. Add new `origin' argument. Use `maybe_load_vmlinux_dwarf_corpus' or `maybe_load_vmlinux_ctf_corpus' according to `origin' value. * src/abg-corpus.h (corpus::origin): Update `origin' type values in enum. * src/abg-corpus-priv.h (corpus::priv): Replace `origin' type from `corpus::origin' to `uint32_t'. * src/abg-corpus.cc (corpus::{get,set}_origin): Replace data type from `corpus::origin' to `uint32_t'. * tools/abidw.cc (main): Use of --ctf argument to set format debug. * tests/test-read-ctf.cc: Add new tests to harness. * tests/data/test-read-ctf/test-PR27700.abi: New test expected result. * tests/data/test-read-ctf/test-anonymous-fields.o.abi: Likewise. * tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-enum-many.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi: Likewise. * tests/data/test-read-common/test-PR26568-2.o: Adjust. * tests/data/test-read-ctf/test-PR26568-1.o.abi: Likewise. * tests/data/test-read-ctf/test-PR26568-2.o.abi: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-B.c: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-B.o: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-array-of-pointers.abi: Likewise. * tests/data/test-read-ctf/test-callback.abi: Likewise. * tests/data/test-read-ctf/test-callback2.abi: Likewise. * tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-dynamic-array.o.abi: Likewise. * tests/data/test-read-ctf/test-enum-ctf.o.abi: Likewise. * tests/data/test-read-ctf/test-enum-symbol.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-enum.o.abi: Likewise. * tests/data/test-read-ctf/test-forward-type-decl.abi: Likewise. * tests/data/test-read-ctf/test-functions-declaration.abi: Likewise. * tests/data/test-read-ctf/test-list-struct.abi: Likewise. * tests/data/test-read-ctf/test0: Likewise. * tests/data/test-read-ctf/test0.abi: Likewise. * tests/data/test-read-ctf/test0.c: Likewise. * tests/data/test-read-ctf/test0.hash.abi: Likewise. * tests/data/test-read-ctf/test1.so.abi: Likewise. * tests/data/test-read-ctf/test1.so.hash.abi: Likewise. * tests/data/test-read-ctf/test2.so.abi: Likewise. * tests/data/test-read-ctf/test2.so.hash.abi: Likewise. * tests/data/test-read-ctf/test3.so.abi: Likewise. * tests/data/test-read-ctf/test3.so.hash.abi: Likewise. * tests/data/test-read-ctf/test4.so.abi: Likewise. * tests/data/test-read-ctf/test4.so.hash.abi: Likewise. * tests/data/test-read-ctf/test5.o.abi: Likewise. * tests/data/test-read-ctf/test7.o.abi: Likewise. * tests/data/test-read-ctf/test8.o.abi: Likewise. * tests/data/test-read-ctf/test9.o.abi: Likewise. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Add Logic to detect file type by extensionvsoch2022-05-121-0/+4
| | | | | | | | | | | | | | Fedabipkgdiff uses mimetypes to detect what file type it is looking at. In some minimal versions of the OS, in particular container images, the package that includes all the mimetypes may not be installed. This allows fedabipkgdiff to fall back to using the extension. * tools/fedabipkgdiff - add logic to detect file type by extension Signed-off-by: vsoch <vsoch@users.noreply.github.com> Reviewed-by: Ben Woodard <woodard@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Add an option ignore SONAME differences in librariesBen Woodard2022-05-125-2/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are rare use cases where we do not want to compare the SONAME when testing libraries for compatiblity or diffing libraries. This adds an option to ignore the SONAME when doing the comparison. In these cases, we will edit the application's DT_NEEDED to point to the other library. This reuses the show_soname_change() function and slightly changes its meaning to not only control if the sonames are printed but also if they are compared. There didn't seem to be any other users of this function and slight semantic change seemed harmless. * doc/manuals/abicompat.rst - added new option * doc/manuals/abidiff.rst - added new option to manpage * src/abg-comparison.cc (compute_diff): don't bother comparing the sonames if you aren't going to print them. * tools/abicompat.cc (options::ignore_soname): Add new data member. (parse_command_line): Support the new --ignore-soname command line option. (display_usage): Add a description string for the new --ignore-soname command line option. (create_diff_context): Set the diff_context::show_soname_change from the new options::ignore_soname data member. * tools/abidiff.cc (options::ignore_soname): Add new data member. (display_usage): Add a description string for the new --ignore-soname command line option. (parse_command_line): Support the new --ignore-soname command line option. (set_diff_context_from_opts): Set the diff_context::show_soname_change from the new options::ignore_soname. Signed-off-by: Ben Woodard <woodard@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* symtab: fix up 64-bit ARM address which may contain tagsGiuliano Procida2022-05-043-0/+26
| | | | | | | | | | | | | | | | | | | | | | 64-bit ARM addresses normally have bits 47 to 63 as either all 0 or all 1. If tagging is used, bits 56 to 63 can vary, but the interpretation of such values is as if the bits were all the same as bit 55. Such tagging is used for HWASAN and this affects the ELF symbol values seen in shared libraries. This commit changes the interpretation of 64-bit ARM symbol values by unconditionally extending bit 55 into bits 56 to 63. This fixes missing types for symbols in HWASAN-compiled libraries. * src/abg-elf-helpers.cc: (architecture_is_arm64): Add helper. * src/abg-elf-helpers.h: Likewise. * src/abg-symtab-reader.cc: (get_symbol_value): Adjust 64-bit ARM symbol values by extending bit 55 into bits 56 to 63. Signed-off-by: Giuliano Procida <gprocida@google.com>
* symtab: refactor ELF symbol value tweaksGiuliano Procida2022-05-042-40/+46
| | | | | | | | | | | | | | | | A previous changes duplicated some logic for tweaking ELF symbol values (and possibly updating some bookkeeping information). This change refactors the code so the logic is in one place, in symtab::get_symbol_value. * src/abg-symtab-reader.cc (symtab::load_): Replace address tweaking logic with a call to get_symbol_value. (symtab::add_alternative_address_lookups): Likewise. (symtab::get_symbol_value): New function containing address tweaking logic for PPC and ARM. Signed-off-by: Giuliano Procida <gprocida@google.com>
* ctf-reader: Fix multiple var-decl in anonymous struct/uninonsGuillermo E. Martinez2022-05-026-1/+63
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch avoids multiple inclusion of `var-decl' node for the same field in anonymous struct/union declaration in the abixml, e.g: struct uprobe_task { union { struct { unsigned long vaddr; }; struct { int dup_xol_work; }; }; }; Three `var-decl' nodes are written in abixml file, expected a single one: <var-decl name='dup_xol_work' .../> * src/abg-ctf-reader.cc (process_ctf_sou_members): Remove CTF_MN_RECURSE flag. * tests/data/Makefile.am: Add new input test files. * tests/data/test-read-ctf/test-anonymous-fields.c: New test file. * tests/data/test-read-ctf/test-anonymous-fields.o: New expected test output. * tests/data/test-read-ctf/test-anonymous-fields.o.abi: Likewise. * tests/test-read-ctf.cc: Add new test. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* tools-utils: `entry_of_file_with_name' returns incorrect resultGuillermo E. Martinez via Libabigail2022-05-021-2/+2
| | | | | | | | | | | | | | entry_of_file_with_name uses `string_ends_with' to test if the filename given in the `fts_path' member of `FTSENT' matches the `fname' argument. This result is not correct when in the current directory there are file with names: "./rmdir-xyx", "./dir-xyz" it returns true for both files, this patch fixes this ambiguity by using `basename' instead of `string_ends_with'. * src/abg-tools-utils.cc (entry_of_file_with_name): Replace call `string_ends_with' by `basename'. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Fix typo in abipkgdiff manpageBen Woodard2022-05-021-1/+1
| | | | | | | | | Add double dash to option name in man page. A minor typo. * doc/manuals/abipkgdiff.rst: add missing `--` Signed-off-by: Ben Woodard <woodard@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* ctf-reader: Add support to undefined forward declaration typesGuillermo E. Martinez via Libabigail2022-04-296-0/+121
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Undefined struct/union forward declaration types are not serialized in abixml representation using `class-decl' node. For instance, consider: struct key_type; typedef void (*key_restrict_link_func_t)(struct key_type *type); Expected node: <class-decl name='key_type' ... is-declaration-only='yes'.../> * src/abg-ctf-reader.cc (process_ctf_forward_type): New function. (process_ctf_type): New CTF_K_FORWARD case. * tests/data/test-read-ctf/test-forward-undefine-type-decl.c: New testcase. * tests/data/test-read-ctf/test-forward-undefine-type-decl.abi: New expected result. * tests/data/test-read-ctf/test-forward-undefine-type-decl.o New test input. * tests/test-read-ctf.cc: Add new testcase to test harness. * tests/data/Makefile.am: Add new test input files to test harness. Signed-off-by: Guillermo E. Martinez <guillermo.e.martinez@oracle.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* comparison: Avoid sorting diff nodes with wrong criteriaDodji Seketeli2022-03-107-52/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This should address PR28939, reported at https://sourceware.org/bugzilla/show_bug.cgi?id=28939 In function_type_diff::chain_into_hierarchy, the diff details represented by the diff nodes of the function parameters are already sorted in the vector priv->sorted_changed_parms_by_id_. Note that the sorting of function parameter diff nodes was done using a criterion that takes into account the position of each function parameter. Members of the vector priv->sorted_changed_parms_by_id_ are then added to the diff graph using diff::append_child_node. The problem is that diff::append_child_node sorts the children nodes /again/, this time using a criterion that is different from the one used in function_type_diff::chain_into_hierarchy. This is wrong. This patch prevents diff::append_child_node from sorting the children node because they have been sorted already. * src/abg-comparison.cc (diff::append_child_node): Do not sort children nodes here because they must have been sorted already. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-filter/test41-report-0.txt: Likewise. * tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* comparison: Factorize the code that inserts diff nodes to the graphDodji Seketeli2022-03-072-217/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | During the traversal of the graph of diff nodes, diff::traverse does two things: 1/ If the generic view of the diff node of is not yet connected to the diff graph, then connect it. Note that the typed view of the diff node is always connected to the diff graph. 2/ Visit the diff node using its generic view and visit its children nodes. Looking at the part 1/, I realized that the code connecting the generic view of the diff node to the diff graph was duplicated in every single type of diff node. This patch put that code into diff::finish_diff_type and makes all the different kinds diff node use that (virtual) member function, effectively factorizing that code. * include/abg-comparison.h ({distinct, var, pointer, reference, array, qualified_type, enum, class_or_union, class, union, base, scope, fn_parm, function_type, function_decl, type_decl, typedef}_diff::finish_diff_type): Remove these declarations. * src/abg-comparison.cc ({distinct, var, pointer, reference, array, qualified_type, enum, class_or_union, class, union, base, scope, fn_parm, function_type, function_decl, type_decl, typedef}_diff::finish_diff_type): Remove these definitions. (diff::finish_diff_type): Add the code to connect the children nodes to the current node, making the generic view of the diff node usable to walk the graph. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* comparison: Describe the "generic view" of a diff nodeDodji Seketeli2022-03-073-3/+57
| | | | | | | | | | | | | | | | | To add a node to the diff graph, what is used is the "generic view" (or generic API) of the diff node. To understand the difference between the generic view and the typed view of diff nodes, this patch adds comments to the diff node API. * include/abg-comparison.h (class diff): Add comments to this class. (diff::chain_into_hierarchy): Add comment to this method. * src/abg-comparison-priv.h (diff::priv): Add comment to this class. * src/abg-comparison.cc (diff::finish_diff_type): Add comment to this method. (diff::traverse): Add comment. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Bug 28013 - Acknowledge variadic parameter type is not canonicalizedDodji Seketeli2022-03-0740-79143/+79181
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Variadic parameter types are one of the rare types that should not be canonicalized, just like the void type. These types are created by the system (compiler/libabigail) and thus can be compared in O(1) time. So far, I forgot to prevent the canonicalization of variadic parameter type everywhere, as should have been the case since the recent introduction of the is_non_canonicalized_type function. This patch fixes that. * src/abg-ir.cc (is_non_canonicalized_type): Recognize variadic parameter types. * tests/data/test-diff-filter/test-PR28013-fn-variadic.c.{0,1}.abi: New test inputs. * tests/data/test-diff-filter/test-PR28013-fn-variadic.c.report.txt: Likewise. * tests/data/Makefile.am: Add the new test files to source distribution. * tests/test-diff-filter.cc (in_out_specs): Add the new tests to this harness. * tests/data/test-annotate/libtest23.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test0.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-filter/test-PR28013-fn-variadic.c.0.abi: Likewise. * tests/data/test-diff-filter/test-PR28013-fn-variadic.c.1.abi: Likewise. * tests/data/test-diff-filter/test-PR28013-fn-variadic.c.report.txt: Likewise. * tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Likewise. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise. * tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi: Likewise. * tests/data/test-read-dwarf/libtest23.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise. * tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * tests/data/test-read-dwarf/test0.hash.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* dwarf-reader: Don't propagate canonical type upon aggregate redundancyDodji Seketeli2022-03-031-1/+8
| | | | | | | | | | | | | | | | | | | | | | | This comes from trying to fix https://sourceware.org/bugzilla/show_bug.cgi?id=26646. During DIE comparison for the purpose of DIE canonicalization, we need to detect a loop due to a recurring aggregate comparison. Thus, the compare_dies function returns true in when it detects that it's comparing two aggregate that are already being compared. In that situation of "detected aggregate redundancy", even though the comparison seemingly succeeds, no canonical type propagation should happen. This patch prevents canonical type propagation when compare_dies return true to signal aggregate redundancy detection. This addresses https://sourceware.org/bugzilla/show_bug.cgi?id=26646#c21. * src/abg-dwarf-reader.cc (compare_dies): Do not propagate canonical type when aggregate redundancy is detected. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Bug 26646 - unexpected declaration-only types (part 2)Dodji Seketeli2022-03-021-37/+97
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch addresses the comment https://sourceware.org/bugzilla/show_bug.cgi?id=26646#c15 of the reported problem. The core of the problem seems to be that when compare_dies compares two DW_TAG_{structure,union}_type, it "gives up" when the comparison stack contains more than 5 such DIEs being compared. Giving up means that it considers the two DIEs to be equivalent if they have the same size and kind, basically. This is to avoid infinite loops or too long loops that we've seen with artificial DWARF input generated by fuzzers. This patch fixes that by better using the "aggregates_being_compared" data structure that is meant to prevent looping infinitely over aggregate DIEs that might be recursively defined. That data structure now contains the DWARF offset pairs of the DIEs being compared, rather than their "string representation". Lookups in that data structure should now be faster and more precise. The artificial limit of the comparison stack not having more than 5 DIEs is now lifted. * src/abg-dwarf-reader.cc (struct dwarf_offset_pair_hash) (dwarf_offset_pair_set_type): Define new type. (die_offset, has_offset_pair, insert_offset_pair) (erase_offset_pair): Define new static helper functions. (compare_dies): Use a set of DWARF offsets for the 'aggregates_being_compared' data structure, rather than a set of string representation of the DIEs. Always look at the size of the types being compared first so that we can get out quickly if they differ. For DIEs of DW_TAG_{union,struct}_type kind, don't limit the depth of the stack of DIEs being compared to 5; so we don't consider two types as being equal just because the depth of the stack being compared is 5 and the two types have the same size and are equal. Hopefully things don't take too long. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* ir: Remove obsolete comment from enumerator equal operatorDodji Seketeli2022-03-011-9/+0
| | | | | | | | | | | While looking at something else, I realized that some parts of the comment of the equal operator of enumerator are obsolete. I am removing it. * src/abg-ir.cc (enum_type_decl::enumerator::operator==): Remove the obsolete parts from the comment. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* reader: Fix a compilation warningDodji Seketeli2022-03-011-3/+5
| | | | | | | * src/abg-reader.cc (build_var_decl): Add braces to an 'if' statement. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* abilint --show-type-use: Show results for global decls that have no symbolsDodji Seketeli2022-02-283-2/+18
| | | | | | | | | | | | | In some abixml file, there can be global decls that don't have ELF symbols. We still want to see how those decls use the type that is being used, as analyzed by abilint --show-type-use <type-id>. * include/abg-fwd.h (is_at_global_scope): Declare ... * src/abg-ir.cc (is_at_global_scope): ... new overload. * tools/abilint.cc (emit_artifact_use_trace): Emit the trace also when the decl is at global scope or has a linkage name. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* abilint: add the --show-type-use optionDodji Seketeli2022-02-284-23/+664
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | "abilint --show-type-use <type-id> <abixml-file>" is a facility that shows how a type defined in an abixml file is used. That is, it emits a textual representation of how the use a type is used up until the function or global variable that constitutes an entry point in the API corpus. Here is an example of its use: test-read-write$ abilint --noout --show-type-use type-id-5 test17.xml Type ID 'type-id-5' is for type 'enum E' The usage graph for that type is: | -> enum E -> E S::m2 -> class S -> S* -> method void S::S() | -> enum E -> E S::m2 -> class S -> S* -> method void S::__base_ctor () | -> enum E -> E S::m2 -> class S -> S* -> method void S::__comp_ctor () | -> enum E -> E S::m2 -> class S -> S* -> method void S::S(S&) | -> enum E -> E S::m2 -> class S -> S* -> S& -> method void S::S(S&) | -> enum E -> E S::m2 -> class S -> S* -> S& -> S var | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> method void S::S() | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> method void S::__base_ctor () | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> method void S::__comp_ctor () | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> method void S::S(S&) | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> S& -> method void S::S(S&) | -> enum E -> E S::m2 -> class S -> S* -> S& -> E S::m2 -> class S -> S* -> S& -> S var $ The screenshot above should be self explanatory. This facility is useful to analyse type usage and find potential issues in how libabigail represents some types. To activate this feature, one needs to configure the package with the configure option "--enable-show-type-use-in-abilint". * configure.ac: Define the --enable-show-type-use-in-abilint configure option. It defines the WITH_SHOW_TYPE_USE_IN_ABILINT macro. * include/abg-reader.h (read_translation_unit): Add an overload that takes the read context. (get_types_from_type_id, get_artifact_used_by_relation_map): Declare new functions. * src/abg-reader.cc (get_types_from_type_id) (get_artifact_used_by_relation_map): Declare these functions as friend of the read_context type. (read_context::m_artifact_used_by_map): (read_context::key_type_decl): Replace the shared_ptr<type_base> type of the first parm by the equivalent type_base_sptr type. (read_context::{record_artifact_as_used_by, record_artifacts_as_used_in_fn_decl, record_artifacts_as_used_in_fn_type}): Add new methods guarded by the WITH_SHOW_TYPE_USE_IN_ABILINT macro. (get_types_from_type_id, get_artifact_used_by_relation_map): Define new functions guarded by the WITH_SHOW_TYPE_USE_IN_ABILINT macro. (read_translation_unit): Define new overload. (RECORD_ARTIFACT_AS_USED_BY, RECORD_ARTIFACTS_AS_USED_IN_FN_DECL) (RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE): Define new macros. (build_function_decl, build_var_decl, build_qualified_type_decl) (build_pointer_type_def, build_reference_type_def) (build_function_type, build_array_type_def, build_enum_type_decl) (build_typedef_decl, build_class_decl, build_union_decl): Use the macros above to mark the relevant sub-types as used by the artifact being built. * tools/abilint.cc (struct artifact_use_relation_tree): Define new type, guarded by the WITH_SHOW_TYPE_USE_IN_ABILINT macro. (fill_artifact_use_tree, build_type_use_tree, emit_trace) (emit_artifact_use_trace, emit_artifact_use_trace) (show_how_type_is_used): Define static functions guarded by the WITH_SHOW_TYPE_USE_IN_ABILINT macro. (display_usage): Add doc string for the --show-type-use option, guarded by the WITH_SHOW_TYPE_USE_IN_ABILINT macro. (parse_command_line): Parse the --show-type-use option, guarded by the WITH_SHOW_TYPE_USE_IN_ABILINT macro. (main): Slight re-organisation to make the abixml file reading use a read_context. That read context is then used to analyze how a given type is used whenever the --show-type-use option is used. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* configure: Remove use of obsolete AC_CONFIG_HEADERDodji Seketeli2022-02-281-1/+1
| | | | | | | * configure.ac: Replace the use of the obsolete AC_CONFIG_HEADER by AC_CONFIG_HEADERS. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Improve some grammarRandy MacLeod2022-02-254-12/+11
| | | | | | | | | | | | Fix typos and try to improve some grammar in the files in the top level directory. * COMPILING: Improve grammar * CONTRIBUTING: Improve grammar * README: Improve grammar * VISIBILITY: Improve grammar Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com>