As Jianfeng Fan pointed out in a comment at
https://sourceware.org/bugzilla/show_bug.cgi?id=31513#c14, there is a
thinko in commit
https://sourceware.org/git/?p=libabigail.git;a=commit;h=338394f5454990c715b52bb4bc2ed47b39d6528b.
has_subtype_changes forgets to reset the s_member when f_member is
reset. Both variables should be reset in tandem, just like what is
done in has_offset_changes.
Fixed thus.
* src/abg-comp-filter.cc (has_subtype_changes): Reset s_member in
the loop, just like f_member.
* tests/data/test-abidiff-exit/PR31513/non-regr/report1.txt: Adjust.
* tests/data/test-abidiff-exit/PR31513/non-regr/report2.txt: Adjust.
* tests/test-abidiff-exit.cc (in_out_specs): Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
It has been reported over IRC by Robin Jarry that in some cases,
abidiff would wrongly consider anonymous data members as being
deleted. These are cases where the anonymous data members were moved
into other anonymous data members without incurring any size or offset
change.
This patch reduces (and hopefully eliminates) false positives in
detecting anonymous data members deletion by considering the leaf data
members of the anonymous data members.
It considers that if all leaf data members contained in the previous
anonymous data members are still present in the new version of the
type, then no data member deletion occurred, basically.
The non-regression test added to this patch contains two binaries that
Robin Jarry sent me. They were built for the source code before and
after the patch he submitted at
http://patches.dpdk.org/project/dpdk/patch/20240327091440.1166119-2-rjarry@redhat.com/.
Note that I have also added a synthetic reproducer example I came up
with after understanding the issue at hand.
* src/abg-comparison.cc
(class_or_union_diff::ensure_lookup_tables_populated): If leaf
data members of an anonymous data member are still present in the
new version of the class, then the anonymous data member cannot be
considered as being removed from the second version of the class.
* tests/data/test-abidiff-exit/non-del-anon-dm/non-regr/report0.txt:
Reference test output.
* tests/data/test-abidiff-exit/non-del-anon-dm/non-regr/test0-v{0,1}.c:
Source code of the binary input below.
* tests/data/test-abidiff-exit/non-del-anon-dm/non-regr/test0-v{0,1}.o:
New binary test input.
* tests/data/test-abidiff-exit/non-del-anon-dm/reported/binaries-origin.txt:
File mentioning the origin of the reported binary.
* tests/data/test-abidiff-exit/non-del-anon-dm/reported/librte_graph.so.24.{0,1}:
Binary test input.
* tests/data/test-abidiff-exit/non-del-anon-dm/reported/report0.txt:
Reference test output.
* tests/data/Makefile.am: Add the test material above to source
distribution.
* tests/test-abidiff-exit.cc (in_out_specs): Add test material
above to this harness.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Consider the 'struct type' below and its use in the file
example-v0.cc:
//----> example-v0.cc: <------
struct type
{
int m0;
};
int
use(type& t)
{
return t.m0;
}
//---->8<-----
Now, consider a second version of that program where the data member
of the 'struct type' is moved into a base class:
//----> example-v1.cc: <------
struct base
{
int m0;
};
struct type : public base
{
};
int
use(type& t)
{
return t.m0;
}
//---->8<------
The first and second version of 'struct type' are ABI compatible
because neither the size of 'struct type' nor the offset of the data
member m0 has changed.
But then look at what abidiff says:
$ abidiff example-v0.o example-v1.o || echo "exit code: $?"
Functions changes summary: 0 Removed, 1 Changed, 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1 function with some indirect sub-type change:
[C] 'function int use(type&)' at example-v0.cc:7:1 has some indirect sub-type changes:
parameter 1 of type 'type&' has sub-type changes:
in referenced type 'struct type' at example-v1.cc:6:1:
type size hasn't changed
1 base class insertion:
struct base at example-v1.cc:1:1
1 data member deletion:
'int m0', at offset 0 (in bits) at example-v0.cc:3:1
exit code: 4
$
abidiff considers that the mere addition of a base class constitutes a
potential ABI incompatibility.
Also, abidiff fails to see that although the data member m0 was
removed from 'struct type' itself, it was moved into its new base
type. In practice, the data member m0 is still a member of 'struct
type', by definition of class type inheritance.
Thus, the exit code of abidiff is ABIDIFF_ABI_CHANGE which value is 4.
This patch fixes this problem.
First of all, here is what abidiff now says with this patch:
$ abidiff example-v0.o example-v1.o && echo "return code: $?"
Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
return code: 0
$
In other words, abidiff now recognizes the changes as being ABI
compatible and filters them out by default.
Furthermore, here are the changes that abidiff sees when asked to
avoid filtering these (now considered harmless) changes:
$ abidiff --harmless example-v0.o example-v1.o && echo "return code: $?"
Functions changes summary: 0 Removed, 1 Changed, 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1 function with some indirect sub-type change:
[C] 'function int use(type&)' at example-v0.cc:7:1 has some indirect sub-type changes:
parameter 1 of type 'type&' has sub-type changes:
in referenced type 'struct type' at example-v1.cc:6:1:
type size hasn't changed
1 base class insertion:
struct base at example-v1.cc:1:1
$
We can see that abidiff no longer considers that the data member m0
was deleted.
At its core, this patch teaches
class_diff::ensure_lookup_tables_populated to detect data members
being moved to base classes. That detection prevents the code base to
consider those data members as being removed from the class.
Now that the moved data members are not considered as removed, the
patch goes further to consider data member moves to base classes that
are not accompanied with any size or offset change as being harmless,
and thus, to be filtered out by default.
To that end, the patch teaches categorize_harmful_diff_node that an
added base classes is not necessarily a harmful change if it is not
accompanied with a size or offset change. Rather, an added base
classes (or any change to a class) not accompanied with a size or
offset change is now categorized into
HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY. Note that the previous
HARMLESS_UNION_CHANGE_CATEGORY was renamed into
HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY.
Incidentally, a removal of a base class or any change accompanied with
an offset change is always categorized as harmful change.
The patch also adds several non-regression tests.
* include/abg-comparison.h (typedef string_decl_base_sptr_map):
Move this typedef to include/abg-fwd.h:
(HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY): Inside the enum
diff_category, rename the enumerator
HARMLESS_UNION_CHANGE_CATEGORY into this.
(EVERYTHING_CATEGORY): Adjust this enum to refer to
HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY, no more HARMLESS_UNION_CHANGE_CATEGORY
* include/abg-fwd.h (typedef string_decl_base_sptr_map): Move this
typedef here from abg-comparison.h
(collect_non_anonymous_data_members): Declare new function.
* src/abg-comp-filter.cc (has_offset_changes)
(type_has_offset_changes, has_offset_changes)
(has_subtype_changes, class_diff_has_only_harmless_changes):
Define new static functions.
(base_classes_removed): Rename base_classes_added_or_removed into
this and update comment.
(categorize_harmless_diff_node): Changes that were categorized as
HARMLESS_UNION_CHANGE_CATEGORY is now categorized as
HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY. Also, a diff that
satisfies either union_diff_has_harmless_changes or
class_diff_has_only_harmless_changes is categorized as
HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY.
(categorize_harmful_diff_node): Adjust to invoke
base_classes_removed instead of base_classes_added_or_removed. An
added base class doesn't necessarily qualifies as a harmful change
anymore. Rather, a diff node that carries an offset change as
detected by type_has_offset_changes is categorized as
SIZE_OR_OFFSET_CHANGE_CATEGORY.
* src/abg-comparison.cc (get_default_harmless_categories_bitmap):
Adjust to use
abigail::comparison::HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY
rather than abigail::comparison::HARMLESS_UNION_CHANGE_CATEGORY.
(operator<<(ostream& o, diff_category c)): Likewise.
(class_diff::ensure_lookup_tables_populated): Detect data members
that are moved into base classes to avoid considering those data
members as being removed from the class.
* src/abg-default-reporter.cc (default_reporter::report): Adjust
to use HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY rather than
HARMLESS_UNION_CHANGE_CATEGORY.
* src/abg-ir.cc (collect_non_anonymous_data_members): Define
function overloads.
* tests/data/test-abidiff-exit/PR31513/non-regr/libtest[1-4]-v{0,1}.so:
New binary test input files.
* tests/data/test-abidiff-exit/PR31513/non-regr/report[1-4.txt:
New reference output files.
* tests/data/test-abidiff-exit/PR31513/non-regr/test[1-4]-v{0,1}.cc:
Source code of the binary input files above.
* tests/data/test-abidiff-exit/PR31513/reported/PR31513-reported-report-{1,2}.txt:
New reference output files.
* tests/data/test-abidiff-exit/PR31513/reported/libloremipsum_gcc{7,11}.so:
New binary test input files.
* tests/data/test-abidiff-exit/PR31513/reported/libstdcpp.suppr:
New test suppression file.
* tests/data/Makefile.am: Add new test files above to source
distribution.
* tests/test-abidiff-exit.cc (in_out_specs): Add the new input
test files to this test harness.
* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
Adjust.
* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt:
Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch introduces a new tool named abidb. It manages a Git
repository of the Application Binary Interfaces of a set of shared
libraries. Those ABIs are stored in the Git repository in the form of
ABIXML files.
The tool then supports the verification of the ABI compatibility of a
given binary against the stored ABIs of shared libraries.
* configure.ac: Condition building abidb on the presence of python
and the required modules.
* doc/manuals/Makefile.am: Add the abidb.rst documentation to
source distribution. Distribute the abidb.1 manpage file as well.
* doc/manuals/abidb.rst: New documentation file.
* doc/manuals/conf.py: Configure the generation of the abidb.1
manage from the abidb.rst file above.
* doc/manuals/libabigail-tools.rst: Add a reference to the new
abidb tool.
* tests/Makefile.am: Register runabidb1.sh and runabidb2.sh as
tests for abidb. Register runabidb1.sh.in and runabidb2.sh.in as
input files for autoconf generated runabidb1.sh and runabidb2.sh.
* tests/data/Makefile.am: Add abidb2client.c, abidb2so.c and
abidb2soBAD.c to source distribution.
* tests/data/abidb2client.c: New source file for test input binaries.
* tests/data/abidb2so.c: Likewise.
* tests/data/abidb2soBAD.c: Likewise.
* tests/runtestabidb1.sh.in: New test script input for autoconf generation.
* tests/runtestabidb2.sh.in: Likewise.
* tools/Makefile.am: Add the new abidb tool to the set of tools.
* tools/abidb: The New Tool, ladies and gentlemen!
Signed-off-by: Frank Ch. Eigler <fche@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
It turns out the tool is almost always returning ABIDIFF_OK in weak
mode. Oops. Fixed thus. Also, update the test-abicompat.cc to test
for expected exit codes to catch this kind of regressions in the
future.
* tools/abicompat.cc (perform_compat_check_in_weak_mode): Do not
override the status code when doing the comparison in the reverse
direction.
(compare_expected_against_provided_functions)
(compare_expected_against_provided_variables): Set the status code
close to the detected diff. In the future, this might help us
provide finer grained status.
* tests/test-abicompat.cc (InOutSpec::status): Add a new data
member to represent the expected exit code.
(in_out_specs): Adjust the array of tests.
(main): If the actual exit code is different from the expected
one, then the test failed so let's report it.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch teaches the ABIXML writer to emit information about
undefined interfaces. It also teaches the ABIXML reader to read
information about undefined interfaces.
It introduces two new ABIXML elements:
'undefined-elf-function-symbols' and 'undefined-elf-variable-symbols'
to represent undefined function and variable symbols.
Then, in the 'abi-instr' element functions and variables that
reference undefined elf symbols now have an 'elf-symbol-id' attribute
referencing the undefined symbol listed in the new
'undefined-elf-variable-symbols' or 'undefined-elf-function-symbols'
element.
The patch introduces tests that perform compatibility checks done on
ABIXML files.
* include/abg-writer.h (set_write_undefined_symbols): Declare new
function.
(set_common_options): Use the new set_write_undefined_symbols in
this function template.
* src/abg-dwarf-reader.cc (reader::{get_die_language, die_is_in_c,
die_is_in_cplus_plus, die_is_in_c_or_cplusplus}): Move these
member functions into ...
(get_die_language, die_is_in_c, die_is_in_cplus_plus)
(die_is_in_c_or_cplusplus): ... these static non-member functions.
(fn_die_equal_by_linkage_name): Adjust and remove the now useless
reader parameter.
(compare_dies, get_scope_die, function_is_suppressed)
(variable_is_suppressed): Adjust.
(build_translation_unit_and_add_to_ir): When we are asked to load
undefined symbol, make sure to also analyze top-level class types
and if we are in C++, also analyze top-level unions and structs as
these might also have some undefined interfaces.
* src/abg-reader.cc (build_elf_symbol_db): Let's not construct and
return the symbol DB anymore. Rather, let's let the caller
construct it, so we can just update it with the input gathered.
(read_symbol_db_from_input): Support getting undefined function
and variable symbols from the new undefined-elf-function-symbols
and undefined-elf-variable-symbols elements. Note that undefined
and defined function symbols go into the same symbol DB whereas
undefined and defined variable symbols go into another symbol DB.
Now, we suppose that the variable & symbol DBs are allocated by
the caller. We pass it down to build_elf_symbol_db that populates
it. Maybe we should rename build_elf_symbol_db into
populate_elf_symbol_db.
(reader::read_corpus): Allocate the function
and variable symbol DB and let read_symbol_db_from_input populate
it. Sort functions and variables after reading the whole ABIXML.
* src/abg-writer.cc (write_context::write_context): Define new
data member.
(write_context::write_context): Initialize it.
(write_context::{get,set}::write_undefined_symbols): Define
accessors.
(set_write_undefined_symbols): Define a new function.
(write_context::decl_is_emitted): Add a new overload.
(write_elf_symbol_reference): Add a writer context and a corpus
parameter. If the symbol is not in the corpus or if the symbol is
undefined and we were not asked to emit undefined symbols then do
not emit any reference to it.
(write_translation_unit): Emit the undefined functions and
variables that belong to the current translation unit, along with
their reference to the undefined ELF symbol they are associated
to.
(write_var_decl, write_function_decl): Let
write_elf_symbol_reference decide whether it should emit the
reference to ELF symbol or not, as it now know how to make that
decision.
(write_corpus): Write the undefined function & variable ELF symbol
data bases. These in the new 'undefined-elf-function-symbols' and
'undefined-elf-variable-symbols' elements.
* tools/abidw.cc (options::load_undefined_interfaces): Define new
data member.
(options:options): Initialize it.
(display_usage): Add a help string for the
--no-load-undefined-interfaces option.
(parse_command_line): Parse the --no-load-undefined-interfaces
option.
(set_generic_options): Set the
fe_iface::option_type::load_undefined_interfaces option.
* doc/manuals/abidw.rst: Document the new
--no-load-undefined-interfaces of abidw.
* tests/data/test-abicompat/test10/libtest10-with-exported-symbols.so:
New binary input file.
* tests/data/test-abicompat/test10/libtest10-with-incompatible-exported-symbols.so:
New binary input file.
* tests/data/test-abicompat/test10/libtest10-with-incompatible-exported-symbols.so.abi:
New abixml input file.
* tests/data/test-abicompat/test10/test10-app-with-undefined-symbols:
New binary input file.
* tests/data/test-abicompat/test10/test10-app-with-undefined-symbols.abi:
New abixml input file.
* tests/data/test-abicompat/test10/test10-app-with-undefined-symbols.cc:
New source file for binary test input
* tests/data/test-abicompat/test10/test10-fn-changed-report-0.txt:
New source file for binary test input
* tests/data/test-abicompat/test10/test10-fn-changed-report-1.txt:
New source file for binary test input
* tests/data/test-abicompat/test10/test10-fn-changed-report-2.txt:
New source file for binary test input
* tests/data/test-abicompat/test10/test10-fn-changed-report-3.txt:
New source file for binary test input
* tests/data/test-abicompat/test10/test10-fn-changed-report-4.txt:
New source file for binary test input
* tests/data/test-abicompat/test10/test10-with-exported-symbols.cc:
New source file for binary test input
* tests/data/test-abicompat/test10/test10-with-exported-symbols.h:
New source file for binary test input
* tests/data/test-abicompat/test10/test10-with-incompatible-exported-symbols.cc:
New source file for binary test input
* tests/data/test-abicompat/test10/test10-with-incompatible-exported-symbols.h:
New source file for binary test input.
* tests/data/Makefile.am: Add new test input files to source
distribution.
* tests/test-abicompat.cc (in_out_specs): Add the new test inputs
to this test harness.
* tests/test-annotate.cc (main): Use the new
--no-load-undefined-interfaces option of abidw to keep the old
behavior.
* tests/test-read-common.cc (test_task::serialize_corpus): Do not
emit undefined symbols.
* tests/test-read-dwarf.cc (test_task_dwarf::perform): Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch teaches the BTF reader how to construct an IR for undefined
interfaces. The patch also updates the abicompat tool for BTF
support.
* doc/manuals/abicompat.rst: Update documentation for the --btf
option of abicompat.
* include/abg-elf-reader.h
(elf::reader::{function,variable}_symbol_is_undefined): Declare
new member functions.
* src/abg-btf-reader.cc
(reader::read_debug_info_into_corpus): Sort functions &
variables after canonicalization.
(reader::build_ir_node_from_btf_type): Always call
fe_iface::add_{fn,var}_to_exported_or_undefined_decls with the
decl that was constructed.
(reader::build_function_decl): Support setting an undefined symbol
to the function decl.
(reader::build_var_decl): Likewise, support setting undefined
symbol the variable decl.
* src/abg-elf-reader.cc
((elf::reader::{function,variable}_symbol_is_undefined): Declare
new member functions.): Define new member functions.
* src/abg-symtab-reader.cc
(symtab::{function,variable}_symbol_is_undefined): Return the
undefined symbol that was found.
* src/abg-symtab-reader.h
(symtab::{function,variable}_symbol_is_undefined): Return an
undefined symbol rather than just a boolean value.
* tools/abicompat.cc: Add support for BTF here.
(options::use_btf): Define new data member ...
(options::options): ... and initialize it.
(display_usage): Add a help string for the --btf option.
(parse_command_line): Parse the --btf option.
* tests/data/test-abicompat/test7-fn-changed-report-0.1.txt: New
reference test output file.
* tests/data/test-abicompat/test7-fn-changed-report-2.1.txt:
Likewise.
* tests/data/test-abicompat/libtest7-fn-changed-libapp-btf-v0.so:
New binary input file.
* tests/data/test-abicompat/libtest7-fn-changed-libapp-btf-v1.so:
Likewise.
* tests/data/test-abicompat/test7-fn-changed-app.btf: Likewise.
* tests/data/Makefile.am: Add the new test material to source
distribution.
* tests/test-abicompat.cc (in_out_specs): Add the new test input
to the test harness.
* tests/data/test-abicompat/test7-fn-changed-app.c: Adjust.
* tests/data/test-abicompat/test7-fn-changed-libapp-v0.c:
Likewise.
* tests/data/test-abicompat/test7-fn-changed-libapp-v1.c: Likewise
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Move the code of elf-reader::{variable,function}_symbol_is_exported into
symtab::{variable,function}_symbol_is_exported (where it belongs) and
make the former use the later.
* src/abg-elf-reader.cc (reader::function_symbol_is_exported): Use
the new symtab::function_symbol_is_exported.
(reader::variable_symbol_is_exported): Use the new
symtab::variable_symbol_is_exported.
* src/abg-symtab-reader.cc
(symtab::{function,variable}_symbol_is_exported): Factorize
elf::reader::{function,variable}_symbol_is_exported into this.
* src/abg-symtab-reader.h
(symtab::{function,variable}_symbol_is_exported): Declare new
member functions.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
In the text below, the term interface means the "declaration of either
a function or a global variable".
To analyze the compatibility between an application and a dependent
library, one has essentially to analyze the interfaces of the
application that have undefined symbols (aka undefined interfaces from
the application) and see how they relate to the same interfaces coming
from the library but with symbols that are defined and exported from
the library (aka defined/exported interfaces from the library).
An interface that is undefined in the application and defined in the
library is an interface that the application consumes from the
library.
In other words an undefined interface from an application is an
interface that the application expects and an interface that is
exported by a library is an interface that the library provides.
If comparing the expected interface against the provided interface
yields a meaningful difference, then that might mean there is an
incompatibility between the application and the library on that
interface.
This patch uses this scheme to re-implement the weak mode of ABI
compatibility between an application and a library.
The patch adds the concept of undefined functions and variables to the
ABI corpus. Then it teaches the DWARF reader how to construct the IR
for these undefined interfaces. Then it revisits the weak mode of
operation of abicompat to make it compare the interfaces expected from
the application against the corresponding interfaces provided by
library. The patch also teaches the weak mode abicompat how to detect
incompatibilities between the interfaces that plugin expects and the
interfaces provided by the application.
This patch makes the CTF front-end construct undefined interfaces. A
subsequent patch is needed to construct undefined interfaces from the
BTF front-end however.
* include/abg-corpus.h (corpus::{lookup_variable,
get_undefined_functions, get_undefined_variables}): Declare new
member functions.
(corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns):
Make this return a boolean.
* include/abg-fe-iface.h (fe_iface::options_type): Add a new
load_undefined_interfaces enumerator.
(fe_iface::add_fn_to_exported_or_undefined_decls): Rename
maybe_add_fn_to_exported_decls into this.
(fe_iface::add_var_to_exported_or_undefined_decls): Rename
maybe_add_var_to_exported_decls into this.
* src/abg-btf-reader.cc (reader::build_ir_node_from_btf_type):
Adjust call to maybe_add_fn_to_exported_decls as
add_fn_to_exported_or_undefined_decls. Similarly, adjust call to
maybe_add_var_to_exported_decls as
add_var_to_exported_or_undefined_decls.
* src/abg-corpus-priv.h (corpus::priv::undefined_{fns,vars}): Add
new member variables.
* src/abg-corpus.cc
(corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns):
Return a bool iff the decl was added to the set of exported decls.
(corpus::{lookup_variable, get_undefined_functions,
get_undefined_variables}): Define new member functions.
(corpus::sort_{functions,variables}): Sort the undefined decls
too.
* (corpus::lookup_{function,variable}_symbol): Lookup the symbol
also among undefined symbols, not just among defined symbols.
* src/abg-ctf-reader.cc (reader::process_ctf_archive): Adjust call
to maybe_add_fn_to_exported_decls as
add_fn_to_exported_or_undefined_decls. Similarly, adjust call to
maybe_add_var_to_exported_decls as
add_var_to_exported_or_undefined_decls. Also, sort functions &
variables in the corpus.
* src/abg-dwarf-reader.cc (die_name_and_linkage_name): Define new
static function.
(reader::fixup_functions_with_no_symbols): Adjust call to
maybe_add_fn_to_exported_decls as
add_fn_to_exported_or_undefined_decls.
(reader::{is_decl_die_with_undefined_symbol,
load_undefined_interfaces}): Define new member functions.
(build_translation_unit_and_add_to_ir): Analyze DIEs of interfaces
that have undefined symbols if we were asked to load undefined
interfaces.
(variable_is_suppressed): Add a boolean parameter to tell if the
var is decl-only. Use that decl-only flag to determine if the
variable is suppressed. A non-member decl-only variable won't be
suppressed if we were asked to load undefined interfaces.
(build_or_get_var_decl_if_not_suppressed): Add a boolean parameter
to tell if the var is decl-only.
(potential_member_fn_should_be_dropped): A potential non-virtual
member function with no symbol is now dropped on the floor
regardless of it has a mangled name or not.
(build_var_decl): If the var has an undefined symbol, then set
that symbol.
(build_function_decl): If the function has an undefined symbol,
then set that symbol.
(build_ir_node_from_die): Add a var or function with undefined
symbol to the set of undefined vars or functions of the current
corpus.
* src/abg-fe-iface.cc
(fe_iface::add_fn_to_exported_or_undefined_decls): Renamed
fe_iface::maybe_add_fn_to_exported_decls into this. If the
function has an undefined symbol then add the function to the set
of undefined functions.
(fe_iface::add_var_to_exported_or_undefined_decls): Renamed
fe_iface::maybe_add_var_to_exported_decls into this. If the
variable has an undefined symbol then add the variable to the set
of undefined variables.
* src/abg-ir.cc (elf_symbol::is_variable): Undefined symbol with
type STT_NOTYPE are actually for undefined variables.
(maybe_adjust_canonical_type): It's here, after type
canonicalization that a member function is added to either the set
of defined & exported functions, or to the set of functions with
undefined symbols.
* src/abg-reader.cc (build_function_decl, build_class_decl)
(build_union_decl, handle_var_decl): Adjust.
* src/abg-symtab-reader.cc
(symtab::{lookup_undefined_function_symbol,
lookup_undefined_variable_symbol, function_symbol_is_undefined,
variable_symbol_is_undefined,
collect_undefined_fns_and_vars_linkage_names}): Define new member
functions.
(symtab::symtab): Initialize the new
cached_undefined_symbol_names_ data member.
* src/abg-symtab-reader.h
(symtab::{lookup_undefined_function_symbol,
lookup_undefined_variable_symbol, function_symbol_is_undefined,
variable_symbol_is_undefined,
collect_undefined_fns_and_vars_linkage_names}): Declare new member
functions.
(symtab::{undefined_variable_linkage_names_,
cached_undefined_symbol_names_}): Define new data members.
(symtab::load_): Consider undefined symbol of type STT_NOTYPE as
being undefined global variables. It's what I am seeing in ELF
binaries.
* src/abg-symtab-reader.h
(symtab::{lookup_undefined_function_symbol,
lookup_undefined_variable_symbol, function_symbol_is_undefined,
variable_symbol_is_undefined}): Declare new member functions.
(symtab::{undefined_function_linkage_names_,
undefined_variable_linkage_names_}): Define new member variables.
* src/abg-writer.cc (write_var_decl, write_function_decl): Emit a
reference to a symbol only when the symbol is defined.
* tools/abicompat.cc (report_function_changes)
(report_variable_changes)
(compare_expected_against_provided_functions)
(compare_expected_against_provided_variables): Define new static
functions.
(perform_compat_check_in_weak_mode): Use the new static functions
above. Compare interfaces expected by the application corpus
against interfaces provided by the library. Report the changes.
Do that in the reverse direction as well.
(read_corpus): Instruct the corpus reader to load the set of
undefined interfaces too.
* tests/data/test-abicompat/test6-var-changed-app: Remove file.
* tests/data/test-abicompat/test6-var-changed-app.cc: Likewise.
* tests/data/test-abicompat/libtest6-undefined-var.so: Add new
binary input file.
* tests/data/test-abicompat/test6-undefined-var.cc: Add sourcefile
for the binary input file above.
* tests/data/test-abicompat/test6-var-changed-report-2.txt: New
reference output file.
* tests/data/Makefile.am: Update the list of distributed files
accordingly.
* tests/data/test-abicompat/libtest5-fn-changed-libapp-v0.so:
Adjust.
* tests/data/test-abicompat/libtest5-fn-changed-libapp-v1.so:
Likewise.
* tests/data/test-abicompat/libtest6-var-changed-libapp-v0.so:
Likewise.
* tests/data/test-abicompat/libtest6-var-changed-libapp-v1.so:
Likewise.
* tests/data/test-abicompat/libtest7-fn-changed-libapp-v0.so:
Likewise.
* tests/data/test-abicompat/libtest7-fn-changed-libapp-v1.so:
Likewise.
* tests/data/test-abicompat/libtest8-fn-changed-libapp-v0.so:
Likewise.
* tests/data/test-abicompat/libtest8-fn-changed-libapp-v1.so:
Likewise.
* tests/data/test-abicompat/libtest9-fn-changed-v0.so: Likewise.
* tests/data/test-abicompat/libtest9-fn-changed-v1.so: Likewise.
* tests/data/test-abicompat/test5-fn-changed-app: Likewise.
* tests/data/test-abicompat/test6-var-changed-libapp-v0.cc:
Likewise.
* tests/data/test-abicompat/test6-var-changed-libapp-v1.cc:
Likewise.
* tests/data/test-abicompat/test6-var-changed-report-0.txt:
Likewise.
* tests/data/test-abicompat/test6-var-changed-report-1.txt:
Likewise.
* tests/data/test-abicompat/test7-fn-changed-app: Likewise.
* tests/data/test-abicompat/test7-fn-changed-report-1.txt:
Likewise.
* tests/data/test-abicompat/test7-fn-changed-report-2.txt:
Likewise.
* tests/data/test-abicompat/test8-fn-changed-app: Likewise.
* tests/data/test-abicompat/test8-fn-changed-libapp-v1.c:
Likewise.
* tests/data/test-abicompat/test9-fn-changed-app: Likewise.
* tests/data/test-abicompat/test9-fn-changed-app.cc: Likewise.
* 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/test1.abi: Likewise.
* tests/data/test-annotate/test14-pr18893.so.ab: Likewise.i
* 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/test8-qualified-this-pointer.so.abi:
Likewise.
* tests/data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64--dbus-glib-0.104-3.fc23.armv7hl-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.
* tests/data/test-fedabipkgdiff/test0-from-fc20-to-fc23-dbus-glib-report-0.txt:
Likewise.
* tests/data/test-fedabipkgdiff/test2-dbus-glib-0.100.2-2.fc20--dbus-glib-0.106-1.fc23-report-0.txt:
Likewise.
* tests/data/test-fedabipkgdiff/test3-dbus-glib-0.100.2-2.fc20.i686--dbus-glib-0.106-1.fc23.i686-report-0.txt:
Likewise.
* tests/data/test-fedabipkgdiff/vte291-0.39.1-1.fc22.x86_64--vte291-0.39.90-1.fc22.x86_64-report-0.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/PR26261/PR26261-exe.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/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/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/test8-qualified-this-pointer.so.abi:
Likewise.
* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
Likewise.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
* tests/test-abicompat.cc (in_out_specs): Adjust.
* tests/test-read-ctf.cc (test_task_ctf::perform): Do not load
undefined interfaces, by default.
* tests/test-symtab.cc (Symtab::SimpleSymtabs)
(Symtab::SymtabWithWhitelist, Symtab::AliasedFunctionSymbols):
Adjust the expected undefined variable symbols counts.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When looking at something else, I stumbled upon a crash when testing
for the presence of CTF debug info.
* src/abg-tools-utils.cc (file_has_ctf_debug_info): Do not crash
on empty debug info paths.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* doc/manuals/abidw.rst: Document the -o option.
* tools/abidw.cc (display_usage): Update doc string for the
--out-file|-o option.
(parse_command): Support the -o short option.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Update the assert in build_function_decl to work on
DW_TAG_inlined_subroutine DIEs.
* src/abg-dwarf-reader.cc (build_function_decl): Loosen the assert
to accept DW_TAG_inlined_subroutine DIEs.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Looking at the result of builds on various platforms, it appears that
the order of the method change reports in the
test29-vtable-changes-report-0.txt of runtestdiffdwarf was not stable
across all platforms. debian-armhf was exhibiting this change in
output, for instance:
--- /var/lib/buildbot/workers/wildebeest/libabigail-try-debian-armhf/build/tests/data/test-diff-dwarf/test29-vtable-changes-report-0.txt
2024-03-04 08:56:42.307366590 +0000
+++ /var/lib/buildbot/workers/wildebeest/libabigail-try-debian-armhf/build/tests/output/test-diff-dwarf/test29-vtable-changes-report-0.txt
2024-03-04 09:20:22.146334907 +0000
@@ -19,13 +19,13 @@
implicit parameter 0 of type 'S* const' has sub-type
changes:
in unqualified underlying type 'S*':
pointed to type 'struct S' changed, as being reported
+ 'method virtual S::~S(int)' has some sub-type changes:
+ implicit parameter 0 of type 'S*' has sub-type changes:
+ pointed to type 'struct S' changed, as being reported
'method virtual S::~S()' has some sub-type changes:
implicit parameter 0 of type 'S* const' has sub-type
changes:
in unqualified underlying type 'S*':
pointed to type 'struct S' changed, as being reported
- 'method virtual S::~S(int)' has some sub-type changes:
- implicit parameter 0 of type 'S*' has sub-type changes:
- pointed to type 'struct S' changed, as being reported
'method virtual void S::fn0()' has some sub-type changes:
implicit parameter 0 of type 'S*' has sub-type changes:
pointed to type 'struct S' changed, as being reported
Better handling the sorting of function changes should hopefully fix
this issue.
* src/abg-comparison-priv.h (is_less_than): Declare new helper
function.
(function_decl_diff_comp::operator(const function_decl_diff&,
const function_decl_diff&)):
Use it here.
(virtual_member_function_diff_comp::operator(const function_decl_diff&,
const function_decl_diff&)):
Likewise.
* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
* tests/data/test-diff-dwarf/test29-vtable-changes-report-0.txt:
Adjust.
* tests/data/test-diff-dwarf/test30-vtable-changes-report-0.txt:
Adjust.
* tests/data/test-diff-dwarf/test31-vtable-changes-report-0.txt:
Adjust.
* tests/data/test-diff-dwarf/test41-PR20476-hidden-report-0.txt:
Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The DWARF reader mistakenly considers that if the value of
DW_AT_inline attribute is set to DW_INL_declared_inlined, that means
the function we are looking at was declared inline. Rather, that
means the function was declared inlined *and* was inlined by the
compiler. To have a better coverage of functions that were declared
inline, we need to consider functions which DW_AT_inline attribute is
set to DW_INL_declared_inlined or DW_INL_declared_not_inlined. This
patches fixes that.
I noticed that we were missing concrete instances of inlined functions
as we were taking into account DW_TAG_inlined_subroutine DIEs. This
patch fixes that.
I noticed that finish_member_function_reading (which is called for
virtual member functions that don't have associated an associated elf
symbol in the current translation unit) wasn't taking into account the
inline declaration of virtual member functions. This patch fixes that.
Last but not least, this patch stops considering the change of
inline-ness declaration of functions as being an ABI change. Whenever
that inline-ness declaration change happens alongside a meaningful ABI
change, libabigail will report it, but that alone is not an ABI
change.
All in all, these change fix the fall-out (caught by the CI) from the
previous patch:
3ccfe465 dwarf-reader: Fix DIE origin handling & scope getting
* include/abg-ir.h (function_decl::is_declared_inline): Add a
setter overload.
* src/abg-dwarf-reader.cc (die_is_declared_inline): Take into the
account values DW_INL_declared_inlined and
DW_INL_declared_not_inlined of DW_AT_inline attribute. Not just
DW_INL_declared_inlined.
(finish_member_function_reading): Set the inline-ness declaration
here.
(build_ir_node_from_die): Handle DW_TAG_inlined_subroutine just as
DW_TAG_subprogram.
* src/abg-ir.cc (function_decl::is_declared_inline): Add a setter
overload.
* tests/data/test-annotate/test1.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-diff-dwarf/test42-PR21296-clanggcc-report0.txt:
Likewise.
* tests/data/test-diff-filter/test41-report-0.txt: 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/test14-pr18893.so.abi: Likewise.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
Likewise.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
Likewise.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
Likewise.
* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The previous patch needed the update of a lot of reference tests. I
didn't have dpkg installed on my development box so I missed updating
dpkg-related reference output.
* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt:
Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
While looking at something else, I noticed that a number of times the
code to create the IR for function-decl was adding the function to the
wrong scope, especially for DIEs that had a chain of
DW_AT_abstract_origin *and* DW_AT_specification attributes.
Suppose we are looking at a DIE D that has a DW_AT_abstract_origin
attribute pointing to a DIE D'. D' itself has a DW_AT_specification
that points to D''. The scope of the function should be represented
by the scope DIE of D'', not the scope DIE of D'. Unfortunately
build_ir_node_from_die was sometimes using the scope of D'.
This patch fixes that by introducing a new die_origin_die function
that returns the ultimate origin of a DIE. In the case above, the
ultimate origin of D is D''. die_origin_die is thus used by
get_scope_die and get_scope_for_die to get the correct scope of a DIE.
The code of build_ir_node_from_die that handles DW_TAG_subprogram DIEs
is thus simplified as get_scope_for_die now does the heavy lifting of
handling DW_AT_abstract_origin and DW_AT_specification.
The result is a simpler and easier to maintain build_ir_node_from_die
and hopefully a more correct one. A lot of the ABIXML and the type
denomination in change reports of the test suite have been updated to
reflect the more accurate representation.
* src/abg-dwarf-reader.cc (die_origin_die): New static function.
(get_scope_die, get_scope_for_die): Use the new die_origin_die
above.
(build_ir_node_from_die): Don't handle DW_AT_abstract_origin and
DW_AT_specification here. In general, do not handle getting the
scope. Rather, just rely on get_scope_for_die.
* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Adjust.
* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
* tests/data/test-annotate/test1.abi: Likewise.
* 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/test2.so.abi: Likewise.
* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
Likewise.
* tests/data/test-annotate/test6.so.abi: Likewise.
* tests/data/test-annotate/test8-qualified-this-pointer.so.abi:
Likewise.
* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
Likewise.
* tests/data/test-diff-dwarf/test0-report.txt: Likewise.
* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt:
Likewise.
* tests/data/test-diff-dwarf/test29-vtable-changes-report-0.txt:
Likewise.
* tests/data/test-diff-dwarf/test30-vtable-changes-report-0.txt:
Likewise.
* tests/data/test-diff-dwarf/test31-vtable-changes-report-0.txt:
Likewise.
* tests/data/test-diff-dwarf/test36-ppc64-aliases-report-0.txt:
Likewise.
* tests/data/test-diff-dwarf/test41-PR20476-hidden-report-0.txt:
Likewise.
* tests/data/test-diff-dwarf/test42-PR21296-clanggcc-report0.txt:
Likewise.
* tests/data/test-diff-dwarf/test5-report.txt: Likewise.
* tests/data/test-diff-dwarf/test8-report.txt: Likewise.
* tests/data/test-diff-filter/test0-report.txt: Likewise.
* tests/data/test-diff-filter/test01-report.txt: Likewise.
* tests/data/test-diff-filter/test10-report.txt: Likewise.
* tests/data/test-diff-filter/test13-report.txt: Likewise.
* tests/data/test-diff-filter/test2-report.txt: Likewise.
* tests/data/test-diff-filter/test28-redundant-and-filtered-children-nodes-report-1.txt:
Likewise.
* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
Likewise.
* 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/test31-pr18535-libstdc++-report-0.txt:
Likewise.
* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.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.
* tests/data/test-diff-filter/test41-report-0.txt: Likewise.
* tests/data/test-diff-filter/test9-report.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/test24-soname-report-1.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-report-10.txt:
Likewise.
* tests/data/test-diff-suppr/test24-soname-report-12.txt:
Likewise.
* tests/data/test-diff-suppr/test24-soname-report-14.txt:
Likewise.
* tests/data/test-diff-suppr/test24-soname-report-16.txt:
Likewise.
* tests/data/test-diff-suppr/test24-soname-report-4.txt: Likewise.
* tests/data/test-diff-suppr/test31-report-1.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/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/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/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/test22-pr19097-libstdc++.so.6.0.17.so.abi:
Likewise.
* tests/data/test-read-dwarf/test6.so.abi: Likewise.
* tests/data/test-read-dwarf/test6.so.hash.abi: Likewise.
* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi:
Likewise.
* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi:
Likewise.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
There are cases where a member function C::f has a defined & exported
ELF symbol in a translation unit TU-2, whereas it has no associated
symbol in another translation unit TU-1.
The class C from TU-1 and the class C from TU-2 have the same
canonical type because they are equivalent. Now, suppose it's C from
TU-2 that is the canonical type; that means the canonical type of C
from TU-1 is C from TU-2.
Today, the only types that are emitted in an ABIXML file are canonical
types. So if we want the C::f which has a publicly defined & exported
elf symbol to be emitted in the ABIXML file, then the C::f that is
defined & exported in the ABI corpus should be the C::f from the
canonical class type C i.e, the C::f from TU-2.
In other words, the exported C::f should be the member function of the
canonical type class C.
That means that determining which C::f to export in the ABI corpus
should be done *after* type canonicalization.
Today however, determining which C::f to export is done during the
construction of the IR, in the DWARF reader. That leads to
cases where the exported C::f is the one that has no defined &
exported ELF symbol. As virtual member functions (in particular) are
involved in class type comparison, that could lead to spurious type
changes left and right. Oops.
This patch implements the export of member functions after type
canonicalization in the DWARF reader. Note that CTF and BTF readers
are not impacted as they only support the C language which doesn't
have member functions.
* src/abg-dwarf-reader.cc
(reader::fixup_functions_with_no_symbols): Do not export the
virtual member function here.
(build_ir_node_from_die): For DW_TAG_subprogram DIEs, likewise.
* src/abg-ir.cc (maybe_adjust_canonical_type): Walk the member
functions of the canonical type and export them in the ABI corpus
if they have a defined and exported elf symbol.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
There is some instability in the abixml output whenever two virtual
member functions have the same vtable offset and different mangling
name. This patch takes the mangling into account.
* src/abg-ir.cc (virtual_member_function_less_than::operator()):
Take the linkage name into account during sorting before taking
into account the presence of elf symbols.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
I forgot to port abicompat to the multi-front-end architecture that
was put in place a while ago. Namely, all the other tools now use
abigail::tools_utils::create_best_elf_based_reader to create the best
elf-based reader depending on if they are given DWARF, BTF or CTF
debug information.
This patch make abicompat use
abigail::tools_utils::create_best_elf_based_reader too.
* tools/abicompat.cc (read_corpus): Use
abigail::tools_utils::create_best_elf_based_reader to create the
right reader depending on the debug information at hand.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
In preparation to subsequent patches that perform manipulations of the
corpus interfaces, it appears that we need to add const access to
those corpus interfaces.
* include/abg-comparison.h (typedef string_function_ptr_map): Make
this typedef use a const function_decl*, not just a
function_decl*.
(typedef string_var_ptr_map): Make this typedef use a const
var_decl*, not just a var_decl*.
* include/abg-corpus.h (typedef corpus::functions): Make this
typedef be a vector<const function_decl*>, not just a
vector<function_decl*>.
(corpus::exported_decls_builder::fn_id_maps_to_several_fns):
Adjust declaration to const function_decl*.
* include/abg-fwd.h (typedef istring_var_decl_ptr_map_type)
(typedef istring_function_decl_ptr_map_type): Move these typedefs to
abg-ir.h.
(get_function_id_or_pretty_representation): Use const function_decl*.
* include/abg-ir.h (typedef istring_var_decl_ptr_map_type)
(typedef istring_function_decl_ptr_map_type): Move these here from
abg-fwd.h. Also make these use const var_decl* and const.
function_decl.
* src/abg-comparison-priv.h (sort_string_function_ptr_map)
(sort_string_var_ptr_map): Use vector<const function_decl*> and
vector<const var_decl*> rather than their non-const variants.
* src/abg-comparison.cc (sort_string_function_ptr_map)
(sort_string_var_ptr_map): Likewise.
(corpus_diff::priv::{ensure_lookup_tables_populated,
apply_supprs_to_added_removed_fns_vars_unreachable_types}):
Adjust.
* src/abg-corpus-priv.h (corpus::priv::{fns,vars}): Make these
data members use vector<const function_decl*> and vector<const
var_decl*> types.
* src/abg-corpus.cc
(corpus::exported_decls_builder::fn_id_maps_to_several_fns)
(corpus::maybe_drop_some_exported_decls): Adjust.
(corpus_group::priv::{fns,vars}): Make these data members use
vector<const function_decl*> and vector<const var_decl*> types.
* src/abg-default-reporter.cc (default_reporter::report): In the
overload for const corpus_diff&, adjust.
* src/abg-ir.cc (get_function_id_or_pretty_representation):
Adjust.
* src/abg-leaf-reporter.cc (leaf_reporter::report): In the
overload for const corpus_diff&, adjust.
* tools/abicompat.cc (perform_compat_check_in_normal_mode):
Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
While looking at something else, I noticed that this test was emitting
details about the tests that PASS, cluttering the output a lot. Fixed
thus.
* tests/test-abicompat.cc (main): Don,'t emit details for PASSed
tests.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The first test to fail was causing all subsequent tests to appear as
failing as well. Fixed thus.
* tests/test-alt-dwarf-file.cc (main): Re-set the is_ok variable
to true in the loop.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The PR25409-librte_bus_dpaa.so.20.0.abi test input file was modified
at least because of the patch to fix zero-length arrays IR for
https://sourceware.org/bugzilla/show_bug.cgi?id=31377.
That modification came after the introduction of the pointer-to-member
type feature, which bumped the ABIXML version to 2.3. So,
PR25409-librte_bus_dpaa.so.20.0.abi should see its ABIXML version
change to 2.3 too. This patch makes that adjustment.
The reason why the patch to fix zero-length arrays IR hasn't bumped
the ABIXML version to 2.3 has to do with easing the potential
back-porting into the libabigail-2.4-branch.
* tests/data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi:
Bump ABIXML version to 2.3.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Before C99, the zero-length array GCC extension described at
https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Zero-Length.html would be
represented in DWARF by a DW_TAG_subrange_type DIE with a DW_AT_count
attribute set to zero.
Since the C99 standard, standardized flexible arrays are now the way
to go. They are represented in DWARF by a DW_TAG_subrange_type that
has no DW_AT_lower_bound, no DW_AT_upper_bound and no DW_AT_count
attribute.
Both zero-length and flexible arrays represent in essence the same
thing. So they should be represented by the same libabigail IR.
Instead, the libabigail IR represents them slightly differently. The
former has the upper_bound of the subrange set to -1 while the latter
has it set to zero. Both have the 'is_infinite' property set to true,
meaning that the subrange has an unknown (flexible) number of
elements.
Because the upper_bound of the two sub-ranges are different, the
equals overload for array_type_def::subrange_type returns false,
(wrongly) indicating that the two sub-ranges are different.
In practice, that leads to abidiff emitting spurious changes between
the two types below which should normally represent the same thing:
int foo[0]; // gcc zero-length extension
int foo[]; // c99 flexible array
This patch makes the DWARF reader set the upper_bound of the sub-range
type to zero for zero-length arrays, just like what is done for
flexible arrays. The "is-infinite" property of the sub-range type is
set to true to flag the type as being for a flexible array.
This fixes the issue described above.
* src/abg-dwarf-reader.cc (build_subrange_type): In the absence of
DW_AT_upper_bound and DW_AT_lower_bound, make DW_AT_count being
zero the same as if no DW_AT_count is present.
* src/abg-reader.cc (build_subrange_type): Add a comment about how
things were in the past (before this patch) and document the fact
that we want to stay compatible with ABIXML from before this
patch.
* tests/data/test-abidiff-exit/PR31377/flex/include/rte_pipeline.h:
New header file input for this test.
* tests/data/test-abidiff-exit/PR31377/flex/lib64/librte_pipeline.so.24.1:
New binary input for this test.
* tests/data/test-abidiff-exit/PR31377/reference/include/rte_pipeline.h:
New header file input for this test.
* tests/data/test-abidiff-exit/PR31377/reference/lib64/librte_pipeline.so.24.0:
New binary input for this test.
* tests/data/test-abidiff-exit/PR31377/test-PR31377-report-1.txt:
New reference test output.
* tests/data/Makefile.am: Add the
* tests/data/test-diff-dwarf-abixml/PR25409-librte_bus_dpaa.so.20.0.abi:
Adjust.
* tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Likewise.
* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
* tests/test-abidiff-exit.cc
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch speeds up the lookup of a function or variable using the
function/variable ID. This patch is in preparation of many more
function lookup made during ABIXML emitting by patches coming up in
the future.
* include/abg-corpus.h (corpus::lookup_functions): Take an
interned_string instead of an std::string. Add an overload for
const char* string too, for debugging purposes.
* src/abg-corpus-priv.h (istr_fn_ptr_set_map_type)
(istr_var_ptr_map_type): Define new typedefs.
(corpus::exported_decls_builder::priv::{id_fns_map_,
id_var_map_}): Use the new istr_fn_ptr_set_map_type and
istr_var_ptr_map_type types for these data members.
(corpus::exported_decls_builder::priv::{id_fns_map, id_var_map,
add_fn_to_id_fns_map, var_id_is_in_id_var_map, add_var_to_map,
add_var_to_exported}): Adjust.
(corpus::priv::lookup_functions): Declare new member function.
* src/abg-corpus.cc
(corpus::exported_decls_builder::maybe_add_var_to_exported_vars): Adjust.
(corpus::priv::lookup_functions): Define new member function. The
code here comes from the code that was in
corpus::lookup_functions. This is a factorization of
corpus::lookup_functions.
(corpus::lookup_functions): Take an interned_string instead of the
previous. Factorize the code that was here into the new
corpus::priv::lookup_functions.
* src/abg-dwarf-reader.cc
(reader::symbol_already_belongs_to_a_function): Adjust the call to
corpus::lookup_functions to use an interned_string.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Profiling showed that computing function type names while sorting
types prior to type hashing was taking a lot of time. Caching
function, reference, pointers and qualified type names reduces that
time a lot.
This is what this patch does, in prevision for the up coming type
hashing patch.
* src/abg-ir.cc ({qualified_type_def, pointer_type_def,
reference_type_def}::get_qualified_name): Cache the internal
qualified type name for non-canonicalized types.
(function_type::get_cached_name): Cache the internal function type
name.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Array subranges were introduced to support the Ada language. In doing
so, I forgot to define an enum type_or_decl_kind enumerator for the
array_type_def::subrange_type IR node. This patch fixes that.
* include/abg-ir.h (type_or_decl_kind::SUBRANGE_TYPE): Add a new
enumerator to enum type_or_decl_kind::type_or_decl_kind.
* src/abg-ir.cc (array_type_def::subrange_type::subrange_type):
Use the new type_or_decl_kind::SUBRANGE_TYPE to flag the IR node
representing array_type_def::subrange_type.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When emitting a type referenced type in the ABIXML,
write_decl_in_scope just emits markup for the opening (and closing)
tags for the scopes up until the actual referenced type. Then the
referenced type is emitted.
But then if the referenced type is a member type of a class A, for
instance, the other data members of that class are not emitted. That
can cause the data members of A to be missing. Oops.
To fix that, if a scope of the referenced type is itself a type,
write_decl_in_scope now emits the full type.
* src/abg-writer.cc (write_decl_in_scope): If the scope of the
decl to write is a type that was not yet emitted, then emit it in
full. Otherwise, just do things as we were doing previously.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
If a DIE comes from C, then for that type, namespace support is
disabled. In this case, we mistakenly look at the language of the
current translation unit DIE rather than the language of the DIE
itself. So we mistakenly find that the DIE comes from C when it
actually can come from C++. And we thus mistakenly disable
namespaces.
Fixed thus.
* src/abg-dwarf-reader.cc (build_ir_node_from_die): Use
reader::die_is_in_c rather than looking at the language of the
current translation unit.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The DWARF from some C++ binaries represents unions in a "piece wise"
fashion. When dealing with those unions, we need to avoid adding the
same member twice, just like what we do for classes.
* src/abg-dwarf-reader.cc (add_or_update_union_type): Do not add
an union member that already exists in the union.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
As the same class can be read several times, let's avoid having
duplicates of a given virtual member function.
* src/abg-ir.cc (fixup_virtual_member_function): Check if a
virtual member function with the same linkage name exists already
before adding it in.
* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
Adjust.
* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
Adjust.
* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Adjust.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
Adjust.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
Adjust.
* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
As explained in
https://fedoraproject.org/wiki/Changes/RemovePythonMockUsage,
python-mock is now deprecated. We ought to use mock from the python
standard library instead.
Maxwell G submitted a patch to libabigail's Fedora package in Rawhide
at 405c5046d8.
I am applying this patch inspired from his work here.
* configure.ac: Do not require python-mock anymore.
* tests/mockfedabipkgdiff.in: Use unittest.mock, not mock from
python-mock.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When handling a decl-only base class, add_or_update_class_type asserts
that we need to try to resolve the decl-only base class to its
definition. That makes sense in most cases.
However, in cases where the base class is actually an opaque class
resulting from the use of the --header-dir{1,2} option of abidiff, the
opaque type is by definition a decl-only class artificially created
from a fully defined class.
When the opaque class is anonymous (later named by a typedef),
maybe_schedule_declaration_only_class_for_resolution schedules a
decl-only class named by the empty string for resolution to its
definition. Later when add_or_update_class_type handles the decl-only
base class (now named by a typedef),
reader::is_decl_only_class_scheduled_for_resolution looks for the
typedef name; as the class scheduled for resolution by
maybe_schedule_declaration_only_class_for_resolution was then
anonymous, reader::is_decl_only_class_scheduled_for_resolution returns
false and the assert in add_or_update_class_type fails. It's the
problem reported in this issue. Oops.
When the opaqued decl-only type is anonymous,
maybe_schedule_declaration_only_{class,enum}_for_resolution must NOT
schedule it for resolution to its definition because the scheduled
types for resolution are designated by name. This patch now enforces
that.
It just doesn't make sense to schedule an anonymous type for
resolution to its definition. When the type is later named by a
typedef however, then it's scheduled for resolution to its definition,
as it's no more anonymous at that point. The patch enforces that as
well.
The patch ends up making sure that add_or_update_class_type does /not/
assert that an /anonymous/ decl-only base class is scheduled for
resolution to its definition.
These changes should fix the problem reported at
https://sourceware.org/bugzilla/show_bug.cgi?id=31279.
* src/abg-dwarf-reader.cc
(reader::maybe_schedule_declaration_only_{class,enum}_for_resolution):
Do not schedule anonymous decl-only types for resolution to their
definition.
(build_typedef_type): When an anonymous decl-only type has just
been named by a typedef, schedule it for resolution to its
definition.
(add_or_update_class_type): Do not assert that /anonymous/
decl-only types are scheduled for resolution to their definition.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
In some C++ binaries, DWARF can represent a member variable using a
global variable /definition/ DIE not having a reference attribute
pointing back to the member variable declaration DIE. The only way we
know that the global variable is a definition DIE for a member
variable is because its linkage name demangles to
"foo::bar::var_name", with foo::bar being a class name.
So, for each translation unit, when the DWARF reader reads a global
variable DIE, it builds a variable IR node for it and stashes it on
the side.
Then, when the translation unit is built, the DWARF reader looks at
all the stashed global variables, detects those that are actually
member variables and adds them to their class. But then, before
adding a (former global) variable to its class, the reader has first
to remove it from its global scope. This removal is done by the
function remove_decl_from_scope, which calls
scope_decl::remove_member_decl.
The issue here is that remove_decl_from_scope forgets to unset the
translation unit property of the global variable.
Then, in the particular case of this problem report, when
scope_decl::add_member_decl is called to add the variable to its
class, it detects that the variable belongs to /another/ translation
unit and (rightfully) aborts. Ooops.
This patch fixes the issue by making remove_decl_from_scope remove the
variable from its translation unit too, not just from its scope. The
patch actually delegates the scope & translation unit resetting to
scope_decl::remove_member_decl because it appears to me that this is
where these ought to be handled.
To ensure that the issue is fixed, one needs to unpack the package
webkit2gtk3-2.40.5-1.el9_3.1.x86_64.rpm and run abidw on the binary
$prefix/usr/lib64/libwebkit2gtk-4.0.so.37 like:
$ abidw --noout $prefix/usr/lib64/libwebkit2gtk-4.0.so.37
Given the size of the library, this takes three hours and a half as
well as ~50GB of ram to complete on my system using a non-optimized
debug build of libabigail. We definitely need to invest in more speed
optimizations to handle webkit. That would be for another day, I
guess.
* src/abg-ir.cc (scope_decl::remove_member_decl): Reset the
translation unit and the scope of the removed decl.
(remove_decl_from_scope): Do not reset the scope of the removed
decl here as it's now done above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Check that EM_RISCV is defined in elf.h and if it is then recognize
it in e_machine_to_string, producing "elf-riscv".
* configure.ac: Defining HAVE_EM_RISCV_MACRO if EM_RISCV
is defined in elf.h.
* src/abg-dwarf-reader.cc (e_machine_to_string): Handle
EM_RISCV if HAVE_EM_RISCV_MACRO is defined.
Signed-off-by: Mark Wielaard <mark@klomp.org>
When the die is a member, it is the CU of the die that should not be
in the C language, not the dwarf reader current translation unit.
* src/abg-dwarf-reader.cc (build_ir_node_from_die): ABG_ASSERT
!rdr.die_is_in_c(), not rdr.cur_transl_unit().
Signed-off-by: Mark Wielaard <mark@klomp.org>
This changes the project name from the default "My Project" to
"libabigail".
* doc/website/libabigail-website.doxy: Set PROJECT_NAME to
libabigail.
Signed-off-by: Giuliano Procida <gprocida@google.com>
Recent patches change the ABI of the library, namely, by adding
parameters to functions like is_pointer_type or adding virtual member
functions to classes in the IR. Thus the LIBABIGAIL_SO_CURRENT
version has to be bumped from 3 to 4.
* configure.ac: Set LIBABIGAIL_SO_CURRENT to 4.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>