The user should be able to specify one white list package per kernel
package on the command line. That means the user should be able to
say:
--wp whitelist-pkg1 --wp whitelist-pkg2
on the command line.
This patch adds support for that.
* doc/manuals/abipkgdiff.rst: Update the documentation to say that
--wp can be provided twice, but not more than that.
* tools/abipkgdiff.cc (options::kabi_whitelist_packages): Rename
kabi_whitelist_package to this, and make be of vector<string>
type.
(package::erase_extraction_directories): Erase the white list
package extracted data.
(maybe_handle_kabi_whitelist_pkg, parse_command_line): Adjust.
(main): Make sure there is no more than 2 --wp on the command
line. Associate a white list package to each kernel package on
the command line.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The package passed to the --wp option was not found because we were
not considering the absolute path of that package. Fixed thus.
* tools/abipkgdiff.cc (parse_command_line): Consider the absolute
path of the package given in argument to --wp.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Make these short options be shorter.
* doc/manuals/abipkgdiff.rst: Adjust the documentation.
* tools/abipkgdiff.cc (display_usage): Adjust the usage string.
(parse_command_line): Parse -w instead of --lkaw and --wp
insteadof --lkaw-pkg.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When a class type lookup fails in a the type map of a corpus, the code
goes look the class up in the type maps of a every single translation
unit.
This design dates back from the time where there could be only one
type of a given name present in in the type map of a corpus. When
several types with the same were found, then each type would be
present in the type map of its translation unit, but then no type with
that name would be present in the type map of the corpus.
As a result, when a type was not found in the type map of the corpus,
we were looking for it in the type maps of the translation units.
Now that the type map of the corpus can carry several types with the
same name, we don't need to look in the translation unit anymore.
This patch implements that adjustment.
* src/abg-ir.cc (lookup_class_type): In the overload that looks
for a class name denoted by an interned_string in the corpus, do
not look for the class in the translation units when the type
wasn't found in the type map of the corpus.
(maybe_update_types_lookup_map): Remove the
erase_if_exists_already parameter and the code that uses it.
(lookup_class_type_through_translation_units): Remove this
function that is now useless.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When abipkgdiff compares binaries of a package, it doesn't report
errors like debug info or symbol not found.
This patch fixes that.
* include/abg-dwarf-reader.h (status_to_diagnostic_string):
Declare new function.
* src/abg-dwarf-reader.cc (status_to_diagnostic_string): Define
new function.
* tools/abipkgdiff.cc (compare): Take a new detailed_error_status
parameter.
(compare_task::perform): Get the details of the error, in case the
status of the comparison is ABIDIFF_ERROR.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When a type has a noop qualifier and that noop qualifier disapears in
a subsequent version of that type, the two versions of the type have
different internal pretty representations. And that leads to the type
canonicalization code ending up with two different canonical types for
the two versions, even if they should be considered equivalent.
This patch makes a noop-qualified type have the same internal pretty
representation as its non-qualified variant.
* src/abg-ir.cc (get_name_of_qualified_type): A noop-qualified
type has an empty string as reprsentation for its qualifier.
* src/abg-dwarf-reader.cc (die_qualified_type_name): Adjust to
comply with what is done in get_name_of_qualified_type. Adjust
comment too.
* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
Adjust.
* tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt:
New reference test output.
* tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64.rpm: New
test binary input.
* tests/data/test-diff-pkg/libcdio-0.94-2.fc26.x86_64.rpm: Likewise.
* tests/data/test-diff-pkg/libcdio-debuginfo-0.94-1.fc26.x86_64.rpm: Likewise.
* tests/data/test-diff-pkg/libcdio-debuginfo-0.94-2.fc26.x86_64.rpm Likewise.
* tests/data/Makefile.am: Add the new test inputs to source distribution.
* tests/test-diff-pkg.cc (in_out_specs): Make this test harness run on
the new test inputs above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When a class is compared to its decl-only counterpart, if the user
doesn't want to see decl-only class related change, then do not report
any size change that might result from it.
This was already meant to be implemented but there was a typo. Fixed
thus.
* src/abg-comparison.cc (report_size_and_alignment_changes): Fix
typo.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Sincea little while, libabigail can now handle the presence of several
different class types definition that have the same name.
To handle that, we settled that for types originating from C, a
decl-only class would be considered different from a definition of
that class. Especially during type canonicalization.
Now it seems that it's wrong to consider this only for C types. That
is because the same class type foo, defined in a C header, can be
compile either into a C++ compilation unit, or a C one, in the same
binary. That is, in the same binary, a struct type foo can be seen
defined in a C compilation unit *and* in a C++ compilation unit.
So rigth now, the C++ struct type foo would compare equal to a
decl-only struct foo, but the C struct type foo would compare
different to a decl-only struct foo. This leads to spurious change
reports, especiall in the nmap and mariadb package from Fedora 25,
when we run selfcheck.py on fc25 critpath packages.
This patch makes libabigail always consider -- during type
canonicalization -- that a decl-only class is different from a
definition of that class. Not only for C.
* src/abg-comparison.cc (function_decl_diff::report): Don't report
possible vtable changes between a decl-only class and its
definition.
* src/abg-ir.cc (type_base::get_canonical_type_for): Consider that
a decl-only class is different from its definition when comparing
types for the purpose of type canonicalization.
(equals): In the class_or_union overload, only consider the global
decl_only_class_equals_definition() property to know when to
consider that a decl-only class is different from its definition
when comparing two classes.
* src/abg-reader.cc (build_class_decl): Read the size property of
a class, even if it's a decl-only class.
* src/abg-writer.cc (write_class_decl_opening_tag): Write size
property of types even if the types are decl-only classes.
* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
* tests/data/test-annotate/test14-pr18893.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-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
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-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/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>
In debug info, some translation units are known to be empty because
they don't carry any DIE. It's thus useless to add those translation
units to the ABI corpus.
Note that in some packages like gcc and glibc (in Fedora 25) the same
empty translation unit can be present in the debug info more than
once. This violates a Libabigail invariant that asserts that a given
translation unit (designated by its path) shall be present only once
in the debug info.
* src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir):
A translation unit DIE that has no child DIE shall not be added to
the current ABI corpus.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This seems to be a typo where I forgot to add a "break" statement in
the stv_to_elf_symbol_visibility function. Oops.
This patch fixes that.
* src/abg-dwarf-reader.cc (stv_to_elf_symbol_visibility): Add a
missing break statement.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
From what I have usually seen emitted by GCC, a "this pointer" is
represented by a DW_TAG_pointer_type. If the "this pointer" is for a
const method, then it points to a const class type DIE.
But in, in this problem report, I am seeing a "this pointer"
represented by a DW_TAG_const_type that points to a
DW_TAG_pointer_type, which is itself points to a class type DIE.
The code of die_this_pointer_is_const needs to be adjusted so that it
doesn't expect only a DW_TAG_pointer_type.
This is what this patch does.
* src/abg-dwarf-reader.cc (die_this_pointer_is_const): If the DIE
is not a DW_TAG_pointer_type then don't crash.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
A prerequisite to represent the relationship "DIE 'D' has canonical
DIE C", is that D and C come from the same DIE source. A DIE source
being either the main debug info file, the alternate debug info file
(both having DIEs in their .debug_info section), or a .debug_type
section.
This prerequisite is a result of the design of the current
libabigail's DWARF reader.
Unfortunately the code that compares DIEs and that updates the
canonical DIEs of the compared DIEs (in case the two DIEs are
equivalent) sometimes fails to honour that prerequisite, causing other
troubles down the road.
This patch fixes that by ensuring that equivalent DIEs must be of the
same DIE source.
The patch doesn't embed a regression test as this problem was
discovered using the
https://pagure.io/libabigail-selfcheck/blob/master/f/selfcheck.py
testing framework
* src/abg-dwarf-reader.cc (compare_dies): Don't propagate
a canonical DIE to a DIE that comes from a different source.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The path of a translation unit is relative to the directory where that
translation unit was compiled.
So there can be several different translation units (in the same
binary) that have the same (relative) paths. To tell them apart, one
needs to consider the compile directory of those translation units.
But then Libabigail ignores the compilation directory of translation
units. It just considers their (relative) path. That leads to
different translation units having the same path.
Furthermore, there can be a translation unit with full path (one that
takes into account the file name and its compile directory) named "P"
that contains function definitions f1 and f2, as described by the
debug info. Further down the road, there can be *another* translation
unit which also has "P" as its full path, and that cotnains function
definitions f3 and f4. A way to understand is to consider that the
translation unit of full path "P" contains f1, f2, f3 and f4.
This patch introduces the concept of the compile dir of a given
translation unit, and the concept of the absolute path of the
translation unit which would then be a concatenation of the compile
dir and relative paths of the translation unit.
The patch also tries to reuse a translation unit with a given path,
*if* that translation unit has already been seen in the current
binary, instead of creating a new one altogether.
This patch doesn't carry a regression test as the problem was found
while running the
https://pagure.io/libabigail-selfcheck/blob/master/f/selfcheck.py
script over the Fedora 25 critpath packages.
The patch does however update existing reference outputs of existings
tests where appropriate.
* include/abg-ir.h (translation_unit::{get_compilation_dir_path,
set_compilation_dir_path, get_absolute_path}):
* src/abg-corpus.cc (corpus::add): Use the new
translation_unit::get_absolute_path() as the key for the tu path
-> tu map.
* src/abg-dwarf-reader.cc
(read_context::resolve_declaration_only_classes): Use the new
translation_unit::get_absolute_path().
(build_translation_unit_and_add_to_ir): Set the compilation
directory of the translation unit.
* src/abg-ir-priv.h (translation_unit::priv::{comp_dir_path_,
abs_path_}):
* src/abg-ir.cc (translation_unit::set_path): Update comment.
(translation_unit::{get_compilation_dir_path,
set_compilation_dir_path, get_absolute_path}): Define new member
functions.
* src/abg-reader.cc (read_translation_unit): Take the new
'comp-dir-path' attribute into account.
* src/abg-writer.cc (write_translation_unit): Emit the new
'comp-dir-path' attribute.
* tests/data/test-annotate/libtest23.so.abi: Adjust.
* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Adjust.
* tests/data/test-annotate/libtest24-drop-fns.so.abi: Adjust.
* tests/data/test-annotate/test0.abi: Adjust.
* tests/data/test-annotate/test1.abi: Adjust.
* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
* tests/data/test-annotate/test2.so.abi: Adjust.
* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
* tests/data/test-annotate/test3.so.abi: Adjust.
* tests/data/test-annotate/test4.so.abi: Adjust.
* tests/data/test-annotate/test5.o.abi: Adjust.
* tests/data/test-annotate/test6.so.abi: Adjust.
* tests/data/test-annotate/test7.so.abi: Adjust.
* tests/data/test-annotate/test8-qualified-this-pointer.so.abi: Adjust.
* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Adjust.
* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Adjust.
* tests/data/test-read-dwarf/test0.abi: Adjust.
* tests/data/test-read-dwarf/test1.abi: Adjust.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
* tests/data/test-read-dwarf/test17-pr19027.so.abi: Adjust.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
* tests/data/test-read-dwarf/test2.so.abi: Adjust.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
* tests/data/test-read-dwarf/test3.so.abi: Adjust.
* tests/data/test-read-dwarf/test4.so.abi: Adjust.
* tests/data/test-read-dwarf/test5.o.abi: Adjust.
* tests/data/test-read-dwarf/test6.so.abi: Adjust.
* tests/data/test-read-dwarf/test7.so.abi: Adjust.
* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When looking at ELF file of the ET_REL kind (i.e, relocatable object
files), several kinds of symbols (for instance weak symbols) can have
the symbol value zero. Although they have the same value, the fact
that that value is zero prevents us from considering those symbols as
being aliases.
Libabigail was wrongly considering those symbols with value zero as
being aliases. So, in practice, it was considering all WEAK symbols
as being aliases, because the value of a weak symbols is zero.
When comparing two binaries originating from the same source code, one
compiled with g++ and the other one compiled with clang++, abidiff was
thus reporting spurious function aliases changes due to this issue.
Note that the two binaries in question come from the bug PR21486.
Comparing them using abidiff exhibits several other issues that were
fixed in previous commits, such as
- Reporting changes about top cv qualifier changes on function
parameter types.
- Not supporting ELF symbol visibility
* src/abg-dwarf-reader.cc (load_symbol_maps_from_symtab_section):
Do not consider symbols with zero value as being aliases.
* tests/data/test-diff-filter/test20-inline-report-0.txt: Adjust.
* tests/data/test-diff-filter/test20-inline-report-1.txt:
Likewise.
* test-diff-filter/test41-PR21486-abg-writer.gcc.o: New test
binary input.
* tests/data/test-diff-filter/test41-PR21486-abg-writer.llvm.o:
Likewise.
* tests/data/Makefile.am: Add the new test material to source
distribution.
* tests/test-diff-filter.cc (in_out_specs): Run the test harness
on the new test input above.
* tests/data/test-diff-dwarf/test5-report.txt: Adjust.
* tests/data/test-diff-filter/test9-report.txt: Adjust.
* tests/data/test-diff-filter/test20-inline-report-0.txt: Adjust.
* tests/data/test-diff-filter/test20-inline-report-1.txt: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When the type of a function parameter sees its top CV qualifier
change, that should never negatively affect ABI compliance.
So this patch filters out top cv qualifier changes on function
parameter types, by default.
* include/abg-comparison.h (enum diff_category): Add a new
FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY enumerator. "Or" the
enumerator to the EVERYTHING_CATEGORY enumerator.
* src/abg-comp-filter.cc (has_fn_parm_type_cv_qual_change): Define
new static function.
(categorize_harmless_diff_node): Categorize changes to top cv
qualifiers on function parameter types into the new
FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY.
* src/abg-comparison.cc (get_default_harmless_categories_bitmap):
Add the new FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY category to the
set of harmless categories.
(operator<<(ostream&, diff_category)): Adjust to serialize
the new FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY.
* tests/data/test-diff-filter/libtest40-v0.so: New test input binary.
* tests/data/test-diff-filter/libtest40-v1.so: Likewise.
* tests/data/test-diff-filter/test40-report-0.txt: New test
reference output.
* tests/data/test-diff-filter/test40-v0.cc: Source code of the
test binary above.
* tests/data/test-diff-filter/test40-v1.cc: Likewise.
* tests/data/Makefile.am: Add the new test material above to
source distribution.
* tests/test-diff-filter.cc (in_out_specs): Add new binaries to
compare.
* 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/test35-pr18754-no-added-syms-report-0.txt:
Likewise.
* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-1.txt:
Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Sometimes some virtual member functions don't have any virtual offset
set in the debug info. This happens for virtual destructors
sometimes. In that case, the ABI change report should not refer to
that unset virtual offset as being '0'. Rather, it shouldn't refer to
it at all.
This is what this patch does.
* include/abg-ir.h (mem_fn_context_rel::mem_fn_context_rel):
Initialize the virtual offset to -1.
* src/abg-comparison.cc (represent): In the overload to represent
a method_decl, do not represent the vofffset if it's not set.
* src/abg-writer.cc (write_voffset): The virtual offset is signed
because if it's -1, it means no offset is set.
* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
Adjust.
* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
Adjust.
* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
Adjust.
* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
Adjust.
* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt: Adjust.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
Adjust.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
Adjust.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
Adjust.
* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When a class is forward-declared, resolving it to a definition that
appears later in the same translation unit or in another translation
is an interesting problem.
Until now, the declaration would be resolved to the definition of that
class found in the binary. The problem is that there can be different
such definitions, especially in C where there is no "One Definition
Rule". In that case, the definition chosen is random.
This patch resolves that randomness.
For a given class declaration, if there is just one possible
definition in the binary, then the declaration is resolved to that
definition. If there is one definition for that declaration in the
same translation unit, then the declaration is resolved to that
definition. If there are more than one definitions in translation
units that are not the one of the declaration, then the declaration is
left unresolved. This is what I call "selective class declaration resolution".
Note that an unresolved class declaration now compares different to a
definition of a class of the same name. This is so that we can have
an unresolved class be present in the resulting .abi file, alongside
an (incompatible) definition of the same class. The change from a class
declaration to its definition is filtered out by default, though.
* include/abg-fwd.h (type_base_wptrs_type)
(istring_type_base_wptrs_map_type): Define new typedefs.
(lookup_class_types): Declare new functions.
* include/abg-ir.h
(environment::decl_only_class_equals_definition): Declare new
accessor.
(type_maps::{*_types}): Make these accessors return
istring_type_base_wptrs_map_type& instead of
istring_type_base_wptr_map_type&.
* src/abg-dwarf-reader.cc
(read_context::resolve_declaration_only_classes): Implement the
new selective declaration resolution scheme.
* src/abg-ir.cc (type_maps::priv::{*_types_}): Change the type of
these data members from istring_type_base_wptr_map_type to
istring_type_base_wptrs_map_type.
(type_maps::{*_types}): Make these accessors definitions return
istring_type_base_wptrs_map_type& instead of
istring_type_base_wptr_map_type&.
(translation_unit::bind_function_type_life_time): Adjust.
(environment::priv::decl_only_class_equals_definition_): New data
member.
(environment::priv::priv): Initialize it. By default, a decl-only
class is now considered different from its definition.
(environment::decl_only_class_equals_definition): Define new
accessor.
(lookup_types_in_map, lookup_class_types): Define new functions.
(lookup_type_in_map, lookup_union_type_per_location)
(lookup_basic_type, lookup_basic_type_per_location)
(lookup_class_type, lookup_class_type_per_location)
(lookup_union_type, lookup_enum_type)
(lookup_enum_type_per_location, lookup_typedef_type)
(lookup_typedef_type_per_location, lookup_qualified_type)
(lookup_pointer_type, lookup_reference_type, lookup_array_type)
(lookup_function_type, maybe_update_types_lookup_map)
(maybe_update_types_lookup_map<class_decl>)
(maybe_update_types_lookup_map<function_type>): Adjust.
(type_base::get_canonical_type_for): When doing type comparison
here, we can now consider that an unresolved class declaration
compares different to an incompatible class definition of the same
name. So no need to look through decl-only classes in that case.
(equals): In the overload for class_or_union, if
environment::decl_only_class_equals_definition() is false, then an
unresolved class declaration of name "N" compares different to a
class definition named "N".
* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt:
Adjust.
* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
Adjust.
* tests/data/test-diff-filter/test38/Makefile: New test material.
* tests/data/test-diff-filter/test38/test38-a.c: Likewise.
* tests/data/test-diff-filter/test38/test38-b.c: Likewise.
* tests/data/test-diff-filter/test38/test38-c.c: Likewise.
* tests/data/test-diff-filter/test38/test38-report-0.txt: Likewise.
* tests/data/test-diff-filter/test38/test38-v0: Likewise.
* tests/data/test-diff-filter/test38/test38-v1: Likewise.
* tests/data/test-diff-filter/test38/test38.h: Likewise.
* tests/data/test-diff-filter/test39/Makefile: Likewise.
* tests/data/test-diff-filter/test39/test39-a-v0.c: Likewise.
* tests/data/test-diff-filter/test39/test39-a-v1.c: Likewise.
* tests/data/test-diff-filter/test39/test39-b-v0.c: Likewise.
* tests/data/test-diff-filter/test39/test39-b-v1.c: Likewise.
* tests/data/test-diff-filter/test39/test39-c-v0.c: Likewise.
* tests/data/test-diff-filter/test39/test39-c-v1.c: Likewise.
* tests/data/test-diff-filter/test39/test39-main.c: Likewise.
* tests/data/test-diff-filter/test39/test39-report-0.txt: Likewise.
* tests/data/test-diff-filter/test39/test39-v0: Likewise.
* tests/data/test-diff-filter/test39/test39-v1: Likewise.
* tests/data/test-diff-filter/test39/test39.h: Likewise.
* tests/data/Makefile.am: Add the new test material above to the
source distribution.
* tests/test-diff-filter.cc (in_out_specs): Add the new test
inputs above to the test harness.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Right now, when loading each corpus of a group, a new read_context is
created and destroyed. That makes thousands of corpora that are
created and destroyed. Profiling seems to argue that we'd gain in
performance by re-using the first read_context that was created
instead, and re-set it before loading a new corpus.
This is what this patch does.
* include/abg-dwarf-reader.h (reset_read_context): Declare new
function.
* src/abg-dwarf-reader.cc (read_context::elf_paths_): Make this to
be non const.
(read_context::initialize): New function to initialize all data
members.
(read_context::read_context): Use the new read_context::initialize
function, rather than initializing data members 'inline' here.
(reset_read_context): Define a new function to reset a
read_context so that it can be re-used to load a new corpus.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When using abidw to generate an abixml for a Linux Kernel build tree,
usually, people have to copy the vmlinux binary into the directory
where modules are, so that the tool can find it. This --vmlinux
option helps to avoid doing that copy.
Simarly, when comparing two Linux Kernel build trees, --vmlinux1 and
--vmlinux2 are there to make the tool find the vmlinux binaries to
compare, independantly from the directories under which the modules
are to be found.
* include/abg-tools-utils.h
(build_corpus_group_from_kernel_dist_under): Add a new
vmlinux_path parameter.
* src/abg-tools-utils.cc (find_vmlinux_and_module_paths): Do not
try to find a vmlinux binary if we already have the path to one.
(build_corpus_group_from_kernel_dist_under): Add a new
vmlinux_path parameter.
* tools/abidw.cc (options::vmlinux): New data member.
(display_usage): Add a usage string for --vmlinux
(parse_command_line): Parse the new --vmlinux option.
(load_kernel_corpus_group_and_write_abixml): Fix some return code
when the function fails. Verify the presence of the vmlinux
binary that was given. Adjust.
* tools/kmidiff.cc (options::{vmlinux1, vmlinux2}): New data
members.
(display_usage): Add a usage string for --vmlinux1 and --vmlinux2.
(parse_command_line): Parse the --vmlinux1 and --vmlinux2
options.
(main): Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
get_type_name can be called over and over again on function types.
This patch caches the result of the computation of function type names
in those cases.
This is a speed optimization.
* src/abg-ir.cc (get_type_name): Cache function type names.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-reader.cc (build_enum_type_decl): Do not check for
errno which might have been set earlier by something else.
Rather, check the returned value for overflow or underflow.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Sometimes some virtual member functions don't have any virtual offset
set in the debug info. This happens for virtual destructors
sometimes. In that case, the ABI change report should not refer to
that unset virtual offset as being '0'. Rather, it shouldn't refer to
it at all.
This is what this patch does.
* include/abg-ir.h (mem_fn_context_rel::mem_fn_context_rel):
Initialize the virtual offset to -1.
* src/abg-comparison.cc (represent): In the overload to represent
a method_decl, do not represent the vofffset if it's not set.
* src/abg-writer.cc (write_voffset): The virtual offset is signed
because if it's -1, it means no offset is set.
* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
Adjust.
* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
Adjust.
* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
Adjust.
* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
Adjust.
* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt: Adjust.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
Adjust.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
Adjust.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
Adjust.
* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
For DIE originating from C, we now compute canonical DIEs. We then
use that to compare DIEs to see if they are equal or not. So string
representation of DIEs are now used only to reduce the number of DIEs
comparisons that is performed during DIE canonicalization.
We can thus just use function names (rather than a full
die_function_signature) as a way to reduce the number of structural
comparisons of DIEs during canonicalization.
This patch does just that.
Note that in the future when we perform DIEs canonicalization and comparison for
C++, we can avoid computing full function DIE signatures for C++ too.
* src/abg-dwarf-reader.cc (die_function_signature): For C DIEs,
just return the (linkage) name of the function.
* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When a class is forward-declared, resolving it to a definition that
appears later in the same translation unit or in another translation
is an interesting problem.
Until now, the declaration would be resolved to the definition of that
class found in the binary. The problem is that there can be different
such definitions, especially in C where there is no "One Definition
Rule". In that case, the definition chosen is random.
This patch resolves that randomness.
For a given class declaration, if there is just one possible
definition in the binary, then the declaration is resolved to that
definition. If there is one definition for that declaration in the
same translation unit, then the declaration is resolved to that
definition. If there are more than one definitions in translation
units that are not the one of the declaration, then the declaration is
left unresolved. This is what I call "selective class declaration resolution".
Note that an unresolved class declaration now compares different to a
definition of a class of the same name. This is so that we can have
an unresolved class be present in the resulting .abi file, alongside
an (incompatible) definition of the same class. The change from a class
declaration to its definition is filtered out by default, though.
* include/abg-fwd.h (type_base_wptrs_type)
(istring_type_base_wptrs_map_type): Define new typedefs.
(lookup_class_types): Declare new functions.
* include/abg-ir.h
(environment::decl_only_class_equals_definition): Declare new
accessor.
(type_maps::{*_types}): Make these accessors return
istring_type_base_wptrs_map_type& instead of
istring_type_base_wptr_map_type&.
* src/abg-dwarf-reader.cc
(read_context::resolve_declaration_only_classes): Implement the
new selective declaration resolution scheme.
* src/abg-ir.cc (type_maps::priv::{*_types_}): Change the type of
these data members from istring_type_base_wptr_map_type to
istring_type_base_wptrs_map_type.
(type_maps::{*_types}): Make these accessors definitions return
istring_type_base_wptrs_map_type& instead of
istring_type_base_wptr_map_type&.
(translation_unit::bind_function_type_life_time): Adjust.
(environment::priv::decl_only_class_equals_definition_): New data
member.
(environment::priv::priv): Initialize it. By default, a decl-only
class is now considered different from its definition.
(environment::decl_only_class_equals_definition): Define new
accessor.
(lookup_types_in_map, lookup_class_types): Define new functions.
(lookup_type_in_map, lookup_union_type_per_location)
(lookup_basic_type, lookup_basic_type_per_location)
(lookup_class_type, lookup_class_type_per_location)
(lookup_union_type, lookup_enum_type)
(lookup_enum_type_per_location, lookup_typedef_type)
(lookup_typedef_type_per_location, lookup_qualified_type)
(lookup_pointer_type, lookup_reference_type, lookup_array_type)
(lookup_function_type, maybe_update_types_lookup_map)
(maybe_update_types_lookup_map<class_decl>)
(maybe_update_types_lookup_map<function_type>): Adjust.
(type_base::get_canonical_type_for): When doing type comparison
here, we can now consider that an unresolved class declaration
compares different to an incompatible class definition of the same
name. So no need to look through decl-only classes in that case.
(equals): In the overload for class_or_union, if
environment::decl_only_class_equals_definition() is false, then an
unresolved class declaration of name "N" compares different to a
class definition named "N".
* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt:
Adjust.
* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
Adjust.
* tests/data/test-diff-filter/test38/Makefile: New test material.
* tests/data/test-diff-filter/test38/test38-a.c: Likewise.
* tests/data/test-diff-filter/test38/test38-b.c: Likewise.
* tests/data/test-diff-filter/test38/test38-c.c: Likewise.
* tests/data/test-diff-filter/test38/test38-report-0.txt: Likewise.
* tests/data/test-diff-filter/test38/test38-v0: Likewise.
* tests/data/test-diff-filter/test38/test38-v1: Likewise.
* tests/data/test-diff-filter/test38/test38.h: Likewise.
* tests/data/test-diff-filter/test39/Makefile: Likewise.
* tests/data/test-diff-filter/test39/test39-a-v0.c: Likewise.
* tests/data/test-diff-filter/test39/test39-a-v1.c: Likewise.
* tests/data/test-diff-filter/test39/test39-b-v0.c: Likewise.
* tests/data/test-diff-filter/test39/test39-b-v1.c: Likewise.
* tests/data/test-diff-filter/test39/test39-c-v0.c: Likewise.
* tests/data/test-diff-filter/test39/test39-c-v1.c: Likewise.
* tests/data/test-diff-filter/test39/test39-main.c: Likewise.
* tests/data/test-diff-filter/test39/test39-report-0.txt: Likewise.
* tests/data/test-diff-filter/test39/test39-v0: Likewise.
* tests/data/test-diff-filter/test39/test39-v1: Likewise.
* tests/data/test-diff-filter/test39/test39.h: Likewise.
* tests/data/Makefile.am: Add the new test material above to the
source distribution.
* tests/test-diff-filter.cc (in_out_specs): Add the new test
inputs above to the test harness.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch introduces the concept of canonical DIEs.
To date, when two C types have the same string representation [1] and
are defined at the same location, they are considered to be the same,
just as in C++.
[1]: String representation of a type: For a type named
"Foo" that is a structure, the representation is "struct Foo"
This patch introduces more finesse in determining if two types are
different.
It implements comparing the DIEs of the types, directly from the DWARF
representation. When comparing pointers, typedefs and qualified
types, the underlying type is compared recursively.
The type de-duplication scheme is now centered around two data
structures.
1/ A map that associates the string representation of a type with
a vector of the offsets of the type DIEs that have the same
representation. Members of this vector denotes DIEs of types that
are *different* even if they all have the same representation.
Each DIE in a given vector is the canonical DIE of its class of
equivalence. This map is the map of all canonical DIEs organized
by the representation of those canonical DIEs.
2/ A map that associates the offset of the canonical type DIE with
the resulting internal representation of the type. Here, the
internal representation is an instance of the
abigail::ir::type_base type. This map is the map of the types
associated to the canonical type DIEs.
There is also a vector that associates a DIE 'D' to its canonical DIE
'C'. The index of the vector is the offset of 'D' and the value of
the element at that index is 'C'.
Thus, each time we are about to create (or get) an internal
representation for a type DIE denoted 'D', we first get the canonical
DIE of 'D', denoted C. If C doesn't exist, we create it. That is, we
add a new entry in the map 1/. Then we look in map 2/ to see if the C
(and thus D) has a associated type.
If C has an associated type, we return it.
If C has no associated type, we create a type for it (and thus for D)
and we associate the new type to the offsets of both D and C.
The rest of the patch is mostly boiler plate and adjustment to
accomodate this new de-duplication scheme.
* src/abg-dwarf-reader.cc (die_decl_map_type, die_type_map_type):
Remove these typedefs.
(die_artefact_map_type, istring_dwarf_offsets_map_type): New
typedefs.
(die_is_at_class_scope, die_qualified_type_name)
(die_qualified_decl_name, die_qualified_type_name_empty)
(die_return_and_parm_names_from_fn_type_die)
(die_function_type_is_method_type):
Const-ify the read_context& parameter.
(read_context::die_source_dependant_container_set::get_container):
Likewise.
(read_context::{name_artefacts_map_, per_tu_name_artefacts_map_,
die_decl_map_, alternate_die_decl_map_, type_unit_die_decl_map_,
die_type_map_, alternate_die_type_map_, type_unit_die_type_map_}):
Remove data members.
(read_context::{die_decl_map, alternate_die_decl_map,
associate_die_to_decl_primary, associate_die_to_decl_alternate,
associate_die_to_decl_from_type_unit,
lookup_decl_from_die_offset_primary,
lookup_decl_from_die_offset_alternate,
lookup_decl_from_type_unit_die_offset,
lookup_type_artifact_from_die_per_tu,
lookup_artifact_from_per_tu_die_representation,
associate_die_to_artifact_by_repr,
associate_die_to_artifact_by_repr_internal, clear_die_type_maps}):
Remove member functions.
(read_context::{decl_die_repr_die_offsets_maps_,
type_die_repr_die_offsets_maps_, decl_die_artefact_maps_,
type_die_artefact_maps_, dwarf_expr_eval_context_}): Add new data
members.
(read_context::clear_per_translation_unit_data): Don't clear
read_context::per_tu_name_artefacts_map_ data member as it's
removed.
(read_context::clear_per_corpus_data): Don't clear
read_context::name_artefacts_map_ and all the other relevant data
members that got removed.
(read_context::{dwarf_per_die_source,
decl_die_repr_die_offsets_maps, type_die_repr_die_offsets_maps,
get_canonical_die, get_die_from_offset, decl_die_artefact_maps,
type_die_artefact_maps, dwarf_expr_eval_ctxt}): Add new member
functions.
(compare_dies, compare_as_decl_dies)
(compare_as_type_dies, maybe_finish_function_decl_reading)
(die_is_anonymous): Define new functions.
(read_context::associate_die_to_decl): Remove the
do_associate_by_repr_per_tu parameter. Use the new
read_context::{decl_die_artefact_maps_, get_canonical_die} member
functions.
(read_context::lookup_decl_from_die_offset): Use Dwarf_Off rather
than size_t for the type of the die_offset parameter. Use the
lookup_artifact_from_die_offset member function.
(read_context::lookup_type_artifact_from_die): Const-ify. In one
overload, take a new 'die_as_type' parameter. Use the new
get_canonical_die, type_die_artefact_maps and
decl_die_artefact_maps member functions. In the second overload,
use the first overload.
(read_context::odr_is_relevant): Add an overload that takes a DIE.
(read_context::associate_die_to_type): Remove the
do_associate_by_repr and do_associate_per_tu parameters. Use the
new get_canonical_die and type_die_artefact_maps member functions.
(read_context::lookup_type_from_die): Use the new
lookup_artifact_from_die member function.
(read_context::lookup_type_from_die_offset): Use the new
type_die_artefact_maps member function. When the found artifact
is a function_decl, return its type.
(read_context::schedule_type_for_late_canonicalization): Use the
new get_canonical_die and type_die_artefact_maps member functions.
(die_function_signature): Const-ify. Get the scope name right
even for scopes that are not types.
(die_member_offset): Make eval_last_constant_dwarf_sub_expr use
the new cached DWARF expression evalution context.
(get_parent_die): Support where_offset equals to zero. This means
we are looking at a C binary, basically.
(build_enum_type) : Use the new overload of
read_context::odr_is_relevant that takes a DIE. Adjust.
(add_or_update_union_type, add_or_update_class_type): Don't lookup
classes/unions per location anymore. Now that we can compare DIEs
in a fined grain manner, the approximation of the location is not
useful anymore.
(build_pointer_type)
(build_function_type): Associate DIE to type if we reuse an
existing type.
(build_or_get_fn_decl_if_not_suppressed): When re-using a
function decl internal representation from an equivalent DIE that
we've seen before, it can happen that we want to augment that
function decl internal representation with new properties coming
from the DIE we are currently looking at; do that here.
(is_function_for_die_a_member_of_class): Remove the "where_offset"
parameter.
(add_or_update_member_function): Adjust.
* tests/data/test-annotate/libtest23.so.abi: Adjust.
* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
* 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: Adjust.
* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-0.txt: Adjust.
* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-1.txt: Adjust.
* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Adjust.
* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
* tests/data/test-read-dwarf/test17-pr19027.so.abi: Adjust.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch speeds up the invocation of
corpus_group::get_unreferenced_function_symbols and
corpus_group::get_unreferenced_variable_symbols. It does so by
caching the result of constructing the map of of unreferenced symbol
at the time where each corpus is added to the group.
* src/abg-corpus.cc (corpus_group::unrefed_{fun, var}_symbol_map):
New data members.
(corpus_group::priv::priv): Adjust.
(corpus_group::priv::add_unref_{fun,var}_symbols): Define new
member functions.
(corpus_group::add_corpus): Update the map of unreferenced
symbols.
(corpus_group::get_unreferenced_{function,variable}_symbols)
Adjust logic.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
With this patch, kmidiff knows how to compare a serialized
corpus_group that represents a Kernel Module Interface (a .kmi file)
against either another serialized .kmi file, or against a kernel tree.
The patch extends the abixml reader to make it parse an
'abi-corpus-group' element. To do that, the patch modifies
read_corpus_from_input to make it be capable of parsing several
'abi-corpus' in a row. That modified function is then used by a new
read_corpus_group_from_input, which is itself used by the new public
entry points read_corpus_group_from_native_xml_file and
read_corpus_group_from_native_xml.
With that read_corpus_group_from_native_xml_file building block
function, the kmidiff program is modified so that it can take either
two directory trees, two .kmi files or one directory tree and one .kmi
file.
* include/abg-libxml-utils.h (advance_to_next_sibling_element):
Declare new function.
* src/abg-libxml-utils.cc (go_to_next_sibling_element_or_stay)
(advance_to_next_sibling_element): Define new functions.
* include/abg-reader.h (read_corpus_group_from_input)
(read_corpus_group_from_native_xml)
(read_corpus_group_from_native_xml_file): Declare new functions.
* src/abg-reader.cc (read_context::m_corpus_group): New data
member.
(read_context::{get_corpus_group, set_corpus_group}): Define new
member functions.
(read_translation_unit_from_input): Cleanup logic.
(read_corpus_from_input): Don't assume that the document is
starting with an 'abi-corpus' element. Support the mode where a
caller called the xmlTextReaderExpand function (and so we are
given an expanded xmlNodePtr) and the mode where we need to use
the xmlTextReader API to walk through the 'abi-corpus' element.
Also, if we are building a corpus group, do not clear what used to
be 'per-corpus' data. That data must be shared by all the corpora
of a given abi-corpus-group.
(read_corpus_group_from_input, read_corpus_group_from_native_xml)
(read_corpus_group_from_native_xml_file): Define new functions.
* include/abg-tools-utils.h (FILE_TYPE_XML_CORPUS_GROUP): New
enumerator of the file_type enum.
* src/abg-tools-utils.cc (operator<<): In the overload for
file_type, add a case for the new FILE_TYPE_XML_CORPUS_GROUP.
(guess_file_type): Dectect abi-corpus-group xml element.
* tools/abidiff.cc (adjust_diff_context_for_kmidiff): Define new
static function.
(main): Adjust to handle the new FILE_TYPE_XML_CORPUS_GROUP. That
is, compare two FILE_TYPE_XML_CORPUS_GROUP if they are present.
* tools/abilint.cc (main): Likewise.
* tools/kmidiff.cc (main): Detect that one of two .kmi files are
passed. In that case, load the .kmi file(s), build a corpus_group
of it and use it in the comparison.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
We have the kmidiff program that takes two Linux Kernel trees
containing the vmlinux binary and its modules and compare their Kernel
Module Interface, aka KMI.
We need to be able to serialize (save in a file) a representation of
that KMI. We need to load that KMI back, and compare two serialized
KMIs.
This patch implements the serialization of the KMI of a Linux Kernel
tree. It actually serializes an instance of abigail::ir::corpus_group
that is a collection of instances of abigail::ir::corpus. The KMI of
each individual binary (vmlinux or kernel module) is represented by
one abigail::ir::corpus. All the corpora share the same definitions
of types and decls, whenever that makes sense.
The patch thus factorizes the routines used to walk a Linux kernel out
of the kmidiff program. These routines are then re-used in the abidw
program to make it walk a Linux kernel tree (when the --linux-tree
option is provided), load the vmlinux and module binaries as an
instance of abigail::corpus_group and serialize it out into an output
stream.
* include/abg-tools-utils.h (check_dir)
(get_binary_paths_from_kernel_dist)
(build_corpus_group_from_kernel_dist_under): Declare new
functions. The last two functions are being moved from
tools/kmidiff.cc so that they can be re-used.
* include/abg-writer.h (write_corpus): Declare one overload that
takes a write_context parameter.
(write_corpus_group): Declare three overloads of this new function.
* src/abg-tools-utils.cc (check_dir): Define new function.
(load_generate_apply_suppressions, is_vmlinux, is_kernel_module)
(find_vmlinux_and_module_paths)
(get_binary_paths_from_kernel_dist)
(build_corpus_group_from_kernel_dist_under): Define new functions.
* src/abg-writer.cc (write_context::set_annotate): Define new
member function.
(write_corpus): Add an overload that takes a write_context. Adapt
the existing overload to make it use this new one.
(write_corpus_group): Define this new function and two additional
overloads for it.
* tools/kmidiff.cc (set_suppressions, is_vmlinux)
(is_kernel_module, find_vmlinux_and_module_paths)
(get_binary_paths_from_kernel_dist)
(build_corpus_group_from_kernel_dist_under): Remove.
(main): Adjust the call to
build_corpus_group_from_kernel_dist_under as its arguments are now
adapted since it's been factorized out into abg-tools-utils.h.
* tools/abidw.cc (options::corpus_group_for_linux): Define new
data member.
(options::options): Adjust.
(display_usage): Add help strings for the new --linux-tree option.
(load_corpus_and_write_abixml): Factorize this function out of the
main function.
(load_kernel_corpus_group_and_write_abixml): Define new function.
(main): Use the factorized load_corpus_and_write_abixml and the
new load_corpus_and_write_abixml functions.
* tests/test-read-write.cc: Adjust.
* doc/manuals/abidw.rst: Add documentation for the new
--linux-tree option.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
After the latest commits to avoid emitting empty translation units and
dupicated decls, and also to fix some indention issues in the abixml
output, this patch updates the reference outputs of the abixml
regression tests.
* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
* tests/data/test-read-dwarf/test17-pr19027.so.abi: Adjust.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
It turned out a lot of empty translation unit can make it to the
abixml output. This patch reduces the number of these.
* src/abg-writer.cc (write_corpus): Do not emit a translation
unit that appears empty beforehand.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch avoids emitting the same decl twice in the same ABI corpus
or corpus_group. For the purpose of this duplication detection, a
decl is designated by its pretty representation.
The patch helps to reduce the size of the abixml files drastically by
cutting some of them, especially those representing the KMI of the
linux kernel in more than half.
* src/abg-writer.cc (write_context::m_emitted_decls_map): New data
member.
(write_context::{decl_name_is_emitted, record_decl_as_emitted}):
Define new memeber functions.
(write_translation_unit): Do not emit a decl that has already been
emitted.
(write_var_decl, write_function): Record the decl as emitted.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
abidiff had an --linux-kernel-abi-whitelist option. Rename it
--kmi-whitelist.
* doc/manuals/abidiff.rst: Add documentation for the
--kmi-whitelist option.
* tools/abidiff.cc (display_usage): Emit help string for the
--kmi-whitelist option
(parse_command_line): Parse the new --kmi-whitelist option, of the
-w shortcut.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When writting out the ABI of a Linux kernel binary we must be able to
restrict it to the set of functions and global variables which ELF
symbols have names defined in a white list.
This patch adds that support, using the --kmi-whitelist
option.
* tools/abidw.cc (options::{kabi_whitelist_paths,
kabi_whitelist_supprs}): New data members.
(display_usage): Add a help string for the new --kmi-whitelist
option.
(parse_command_line): Parse the new --kmi-whitelist option.
(maybe_check_suppression_files): Check the presence of the linux
kernel abi white list passed by the option --kmi-whitelist.
(main): Ignore loading the symbol table if the kernel abi white
list is provided.
* doc/manuals/abidw.rst: Add documentation for the new option.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch makes abipkgdiff compare two kernel packages. At the
moment the comparison is done by comparing each binary from the first
package to its counterpart in the second package. No optimization is
done do represent a vmlinux binary and its modules as one single
entity. So this is different from what kmidiff does.
* include/abg-suppression.h
(variable_suppression::variable_suppression): Add default arguments
to the parameters.
* include/abg-tools-utils.h (dir_exists, dir_is_empty)
(string_begins_with, get_rpm_name, get_rpm_arch, get_deb_name)
(file_is_kernel_package, file_is_kernel_debuginfo_package):
Declare new functions.
* src/abg-tools-utils.cc (dir_exists, dir_is_empty)
(string_begins_with, get_deb_name, get_rpm_name, get_rpm_arch)
(file_is_kernel_package, file_is_kernel_debuginfo_package): Define
new functions.
(gen_suppr_spec_from_kernel_abi_whitelist): The kernel ABI
whitelist is made of ELF symbols names that ought to match
functions *and* variables that have ELF symbols with those names.
So generate variable suppression specifications as well. Not just
function suppression specifications.
* tools/abipkgdiff.cc (options::{kabi_whitelist_package,
show_symbols_not_referenced_by_debug_info, kabi_whitelist_paths,
kabi_suppressions}): New data members.
(options::options): Adjust.
(package::KIND_KABI_WHITELISTS): New enumerator in the
package::kind enum.
(package::kabi_whitelist_package_): New data member.
(package::{base_name, kabi_whitelist_package, }): New member
functions.
(display_usage): Add a help string to the new
--linux-kernel-abi-whitelist and --no-unreferenced-symbols
options.
(parse_command_line): Parse the new --no-unreferenced-symbols,
--linux-kernel-abi-whitelist and --lkaw-pkg options.
(maybe_check_suppression_files): Check the presence of kabi
whitelist files.
(set_diff_context_from_opts): Consider (not) showing symbols not
referenced by debug info.
(compare): If we are looking at linux kernel packages, take the
kernel abi whitelist into account, apply the suppressions
resulting from the kabi whitelists to the ELF read context.
(maybe_collect_kabi_whitelists)
(get_kabi_whitelists_from_arch_under_dir)
(maybe_handle_kabi_whitelist_pkg, maybe_collect_kabi_whitelists)
(get_interesting_files_under_dir): Define new functions.
(maybe_update_vector_of_package_content): Take a new
file_name_to_look_for parameter.
(create_maps_of_package_content)
(extract_package_and_map_its_content): Consider the case of the
package being a linux kernel package.
(main): Take the potential --lkaw-pkg into account.
* doc/manuals/abipkgdiff.rst: Add documentation for options
--linux-kernel-abi-whitelist, --lkaw-pkg and
--no-unreferenced-symbols.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Sometimes, it can happen that a translation unit gets read twice while
loading an abixml. This patch fixes that.
* src/abg-reader.cc (read_translation_unit): Take (in parameter) a
reference as the resulting translation unit.
(get_or_read_and_add_translation_unit): Define new static
function.
(read_context::get_scope_for_node)
(read_translation_unit_from_input): Use the new
get_or_read_and_add_translation_unit.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-dwarf-reader.h (set_read_context_corpus_group)
(read_and_add_corpus_to_group_from_elf, set_ignore_symbol_table)
(get_ignore_symbol_table): Declare new functions.
* abg-dwarf-reader.cc (read_context::options_type): Define new
type.
(die_dependant_container_set::clear): Define new member function.
(read_context::{bss, tesxt, rodata, data, data1}_section_): Add
new data members.
(read_context::{symbol_versionning_sections_loaded_,
symbol_versionning_sections_found_}): Likewise.
(read_context::corpus_group_): Likewise.
(read_context::{load_in_linux_kernel_mode, load_all_types,
show_stats, do_log_}): Replace these options by ..
(read_context::options_): ... this instance of the new
read_context:options_type.
(read_context::read_context): Adjust.
(read_context::{clear_alt_debug_info_data, clear_per_corpus_data,
env, get_data_section_for_variable_address, load_all_types,
load_in_linux_kernel_mode, show_stats, do_log}): Adjust.
(create_read_context): Adjust.
(read_context::~read_context): Define destructor.
(read_context::{options, bss_section, text_section,
rodata_section, data_section, data1_section, current_corpus_group,
has_corpus_group, main_corpus_from_current_group,
main_corpus_from_current_group,
current_corpus_is_main_corpus_from_current_group,
should_reuse_type_from_corpus_group}): Define new member
functions.
(read_context::get_die_qualified_type_name): Handle the name of
the current translation unit.
(read_context::load_symbol_maps): Really don't load (linux kernel
specific) symbol maps if we were told to ignore the ELF symbol
table.
(set_ignore_symbol_table, get_ignore_symbol_table)
(create_default_var_sym, create_default_fn_sym, add_symbol_to_map)
(set_read_context_corpus_group)
(read_and_add_corpus_to_group_from_elf): Define new functions.
(build_type_decl, build_typedef_type, build_enum_type)
(add_or_update_class_type)
(add_or_update_union_type): Reuse the type being built, from the
main corpus of the corpus group.
(build_qualified_type): Cleanup logic.
(build_var_decl, build_function_decl): Create a default symbol for
the variable or function if we are supposed to ignore the symbol
table of the current binary. Add that symbol to the symbol table
that is created in the read context.
(read_debug_info_into_corpus): Don't load the ELF symbol table
information if we are asked to ignore the symbol table. But set
the symbol table that we built artificially while loading
functions and variables, into the ABI corpus being built.
(read_context::maybe_adjust_var_sym_address): Adjust.
(build_ir_node_from_die): Add ir node to its logical scope. For
the C language, the scope of a type is the global scope.
(read_corpus_from_elf): Don't load ELF properties if we were asked
to avoid the ELF symbol table.
* include/abg-comparison.h (compute_diff): Declare ...
* src/abg-comparison.cc (compute_diff): ... an overload to compare
corpus_group.
* tools/kmidiff.cc: New tool.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch adds support to associate a type to its source location.
The location being a string of the form "filepath:line:column". The
association is done by a per-translation unit map which associates a
location to a type.
For the moment this only associates one type to a given location. For
the general case, though, we need to associate a vector or types to a
given location. We'll add that support later.
The patch provides lookup functions, each of which looking up a
particular kind of type by its location.
* include/abg-fwd.h (get_name_of_qualified_type)
(get_name_of_reference_to_type, lookup_basic_type_per_location)
(lookup_class_type_per_location, lookup_union_type_per_location)
(lookup_enum_type_per_location, lookup_typedef_type)
(lookup_typedef_type_per_location, lookup_pointer_type)
(lookup_reference_type, lookup_type_per_location)
(lookup_type_through_translation_units)
(lookup_type_from_translation_unit, odr_is_relevant): Declare new
functions or new function overloads.
* include/abg-ir.h (location::expand): Declare new member
function.
(type_maps::empty): Likewise.
(operator|=): Declare an overload for qualified_type_def::CV.
(get_string_representation_of_cv_quals)
(get_name_of_qualified_type, lookup_qualified_type): Declare new functions.
* src/abg-ir.cc (location::expand): Define new member function.
(type_maps::empty): Likewise.
(odr_is_relevant): Likewise.
(get_string_representation_of_cv_quals)
(get_name_of_reference_to_type, get_name_of_qualified_type)
(lookup_union_type_per_location): Define new functions or overloads.
(lookup_basic_type, lookup_enum_type, lookup_typedef_type)
(lookup_qualified_type, lookup_pointer_type)
(lookup_reference_type, lookup_type_from_translation_unit)
(lookup_basic_type_per_location, lookup_basic_type_per_location)
(lookup_class_type_per_location, lookup_class_type_per_location)
(lookup_enum_type_per_location, lookup_enum_type_per_location)
(lookup_typedef_type_per_location)
(lookup_typedef_type_per_location, lookup_type_per_location):
Define new overloads.
(maybe_update_types_lookup_map)
(maybe_update_types_lookup_map<class_decl>)
(maybe_update_types_lookup_map<function_type>): Add a new
use_type_name_as_key parameter. If it's false, then associates
the type to its location rather than to its name.
(maybe_update_types_lookup_map): In the overloads for type_decl,
class_decl, union_decl, enum_type, typedef_decl, array_type_def,
record the type in the lookup map per location, in addition to the
per-name recording.
(qualified_type_def::build_name): Use the new
get_name_of_qualified_type.
(qualified_type_def::get_cv_quals_string_prefix): Use the new
get_string_representation_of_cv_quals.
(operator|=): Define a new overload for qualified_type_def::CV.
(pointer_type_def::get_qualified_name): Use the new
get_name_of_pointer_to_type.
(reference_type_def::get_qualified_name): Use the new
get_name_of_reference_to_type.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
To support the upcomping analysis of the Linux kernel and its modules,
we need a way to represent a union of corpora. The first corpus
loaded would be the one representing the vmlinux binary. Subsequent
corpora loaded would be those representing the modules.
This patch provides the new abigail::ir::corpus_group type that
represents such a corpus group.
* include/abg-corpus.h (corpus::{find_translation_unit,
get_type_per_loc_map}): Declare new member functions.
(corpus::{get_architecture_name, is_empty}): Make these member functions
const.
(corpus::{get_sorted_fun_symbols, get_functions, get_variables,
get_unreferenced_function_symbols,
get_unreferenced_variable_symbols}): Make these member functions
virtual.
(class corpus_group): Declare a new type.
* include/abg-fwd.h (corpus_sptr, corpus_group_sptr)
(string_tu_map_type, istring_var_decl_ptr_map_type)
(istring_function_decl_ptr_map_type): Define new typedefs.
* src/abg-corpus-priv.h (corpus_priv::{path_tu_map,
type_per_loc_map_}): Add new data members.
* src/abg-corpus.cc (corpus_add): Complete the function comment.
Assert that at most one translation unit of a given path can be
added to the corpus.
(corpus::{find_translation_unit, get_type_per_loc_map}): Define
new member functions.
(corpus::{get_architecture_name}): Make this member function
const.
(struct corpus_group::priv): Define new type.
(corpus_group::{corpus_group, ~corpus_group, add_corpus,
get_corpora, is_empty, get_functions, get_variables,
get_var_symbol_map, get_fun_symbol_map, get_sorted_fun_symbols,
get_sorted_var_symbols, get_unreferenced_function_symbols,
get_unreferenced_variable_symbols}): Define member functions of
the new corpus_group type.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The command "fedabipkgdiff --self-compare --from fc25 grub2" returns
with an error because no debug info can be found for the file
kernel.img. That file doesn't have any debug info shipped for it.
And we shouldn't try to compare it anyway.
This patch updates the default suppression file shipped by libabigail
to make it avoid compare kernel.img files.
* default.abignore: Do not compare kernel.img files.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>