The alternate debug info file referred to a binary can be missing,
even though the rest of the debug info is not. In that case,
libabigail starts loading the debug info and then it crashes when
trying to get DIEs that are part of the missing alternate debug info.
This patch detects when the alternate debug info is missing, so that
abidiff and abipkgdiff can gracefully bail out, yielding a meaningful
error message.
* include/abg-dwarf-reader.h (enum abigail::dwarf_reader::status):
Add a new STATUS_ALT_DEBUG_INFO_NOT_FOUND enumerator there.
(refers_to_alt_debug_info): Declare new function.
* src/abg-dwarf-reader.cc (read_corpus_from_elf): Detect when the
referred-to alternate debug info file is not found and flip the
STATUS_ALT_DEBUG_INFO_NOT_FOUND bit of the status accordingly. If
the debug info was found but not the alternate debug info, then do
not try to read the debug info at all.
(refers_to_alt_debug_info): Define new function.
* tools/abidiff.cc (handle_error): Define new static function.
(main): Use it, rather than handling errors preventing libabigail
from reading the corpus on a case by case basis.
tools/abipkgdiff.cc (compare): Handle the case where no alternate
debug info was found.
* tests/data/test-diff-pkg/libxfce4ui-devel-4.12.1-8.fc27.ppc64-self-report-0.txt:
New test output reference.
* tests/data/test-diff-pkg/libxfce4ui-devel-4.12.1-8.fc27.ppc64.rpm:
New test input RPM.
* tests/data/test-diff-pkg/libxfce4ui-devel-debuginfo-4.12.1-8.fc27.ppc64.rpm:
Likewise.
* tests/data/Makefile.am: Add the new test files above to source
distribution.
* tests/test-diff-pkg.cc (in_out_specs): Add a new test case from
the new input files above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
On some 32 systems (older glibc) the fts.h file cannot be included
"as-is" if the _FILE_OFFSET_BITS macro is set to 64.
This patch handles that case gently by including fts.h with
_FILE_OFFSET_BITS unset, but then by making sure fts.h can still
handle 64 bits file offset files.
* configure.ac: Detect if we are on a system where fts.h cannot be
included with _FILE_OFFSET_BITS defined. If that is the case,
then define the BAD_FTS macro.
* src/abg-tools-utils.cc: If BAD_FTS is defined then include fts.h
with _FILE_OFFSET_BITS not defined (that is, before config.h) but
then make sure that open and fopen are 64 bits aware.
* tools/abipkgdiff.cc: Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
While building on an 32 bit intel platform, compilation of
abipkgdiff.cc failed because fts.h wouldn't compile with
the macro _FILE_OFFSET_BITS set to 64. That macro is set by config.h!
The idea of this patch is to make config.h have an effect only on
libabigail's own header files, not on system header files.
* tools/abipkgdiff.cc: Include config.h after system headers and
before libabigail's headers.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Up until now, the --no-show-locs option only had effect when abidiff
was used with the --abidiff option. It had no effect on the ABIXML
output of abidw.
This patch changes that to make it so that --no-show-locs avoids
emitting source location to the ABIXML output.
* doc/manuals/abidw.rst: Update the documentation.
* tests/test-annotate.cc: Now that --no-show-locs has an effect on
the ABIXML output, let's not use it here, because it changes the
output and we don't want that.
* tools/abidw.cc (display_usage): Fix a typo in the help string.
(load_corpus_and_write_abixml): Set the "show-locs" option to the
write_context object that we use.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Up to know, it wasn't possible to set options to instances of
xml_writer::write_context. So it wasn't possible to, say, make abidw
stop emitting source locations in the abixml.
This patch does the work necessary to set two options: annotate and
show locations. Note that the patch doesn't yet enable abidw to stop
emitting source locations. That will be done in a subsequent patch.
* include/abg-writer.h (create_write_context, set_show_locs)
(set_annotate): Declare new functions.
(write_corpus, write_corpus_group): Remove the output stream and
the annotate parameters as these can be retrieved from the
context.
* src/abg-writer.cc (write_context::m_show_locs): New data member.
(write_context::write_context): Initialize it.
(write_context::{get_show_locs, set_show_locs}): Add new member
functions.
(write_location): Take a write_context, rather than an output
stream. From the context, we detect if the user did set the "show
loc" option and act accordingly. Write the second overload in
terms of the first one.
(create_write_context, set_show_locs, set_annotate): Define new
functions.
(write_type_decl, write_qualified_type_def)
(write_pointer_type_def, write_reference_type_def)
(write_array_type_def, write_enum_type_decl, write_typedef_decl)
(write_var_decl, write_function_decl)
(write_class_decl_opening_tag, write_union_decl_opening_tag)
(write_type_tparameter, write_non_type_tparameter)
(write_function_tdecl, write_class_tdecl): Adjust the invocation
of write_location.
(write_corpus, write_corpus_group): Remove the output stream and
the annotate parameters as these can be retrieved from the
context. Adjust.
* tools/abidw.c: (load_corpus_and_write_abixml): Create a
write_context object, set the 'annotate' option to it and use that
object to actually write out the corpus.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-writer.cc (class write_context): Remove useless vertical
space near the end of the class definition.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch adds a --suppressions option to fedabipkgdiff so that a
suppression specification can be applied to the comparisons performed.
* tools/fedabipkgdiff (abipkgdiff): If a suppression file was
provided, pass it to the underlying abipkgdiff tool.
(build_commandline_args_parser): Parse the new --suppressions
option.
* docs/manuals/fedabipkgdiff.rst: Add documentation for the new
--suppressions option.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Handling an exception in fedabipkgdiff requires that the global_config
object is set because we reference some if its data members.
This patch avoids requiring the global_config object so that users can
still be aware of the reason of the exception when that object is not
yet set.
* tools/fedabipkgdiff: When handling an exception, if the
global_config object is not yet set then just let the exception
through.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* tools/abipkgdiff.cc (compare): In the overload of elf_file, fix
a mis-indentation pointed out by a GCC 7.2.1 warning.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-dwarf-reader.cc (die_qualified_type_name): Cleanup a
switch case to make the form support more what we meant, and shut
down a GCC 7.2.1 warning.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
abg-leaf-reporter.cc: In member function ‘virtual void abigail::comparison::leaf_reporter::report(const abigail::comparison::qualified_type_diff&, std::ostream&, const string&) const’:
abg-leaf-reporter.cc:158:3: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
if (!diff_to_be_reported(&d))
^~
abg-leaf-reporter.cc:161:5: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the ‘if’
report_local_qualified_type_changes(d, out, indent);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* src/abg-leaf-reporter.cc (leaf_reporter::report): Fix misleading
indentation.
Signed-off-by: Mark Wielaard <mark@klomp.org>
kmidiff displays leaf changes by default and and it does so by *not*
showing impacted interfaces.
This patch add a --impacted-changes option to kmidiff so that it shows
the interfaces that are impacted by each leaf change. Thus, by
default, no impacted interface is shown.
* doc/manuals/kmidiff.rst: Document the new --impacted-changes
option.
* tools/kmidif.cc (options::show_impacted_interfaces): Add new
data member.
(options::options): Initialize the new data member to false.
(display_usage): Add a description string for the new
--impacted-changes option.
(parse_command_line): Parse the new --impacted-changes option.
(set_diff_context): Update the 'show-impacted-interface' property
accordingly.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch changes the default report emitted by kmidiff. Now, it
emits a leaf changes report by default. And if the user wants the
classical kind of report then she can use the --full-impact option.
* doc/manuals/kmidiff.rst: Add documentation for the new
--full-impact|-f option.
* tools/kmidiff.cc (options::leaf_changes_only): Add new data
member.
(option::option): Initialize the new data member.
(display_usage): Add a documentation string for the new
--full-impact|-f option.
(parse_command_line): Parse the new --full-impact|-f option.
(set_diff_context): Set the diff context appropriately.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch adds the --leaf-changes-only option to abipkgdiff, just
like what we have for abidiff. The patch also emit leaf changes
report by default when comparing two Linux Kernel packages.
The patch also adds the --impacted-interfaces and --full-impact
options.
* doc/manuals/abipkgdiff.rst: Add documentation for the new
--leaf-change-only, --impacted-interfaces and --full-impact
options.
* tools/abipkgdiff.cc (options::{leaf_changes_only,
show_impacted_interfaces, show_full_impact_report): Add new data
members.
(options::options): Initialize them.
(display_usage): Add help strings for the new --leaf-change-only,
--impacted-interfaces and --full-impact|-f options.
(set_diff_context_from_opts): Set the diff context for the
'leaf-changes-only' and 'show-impacted-interfaces' flags.
(parse_command_line): Parse the --leaf-change-only,
--impacted-interfaces and --full-impact options. Handle the case
where the --linux-kernel-abi-whitelist|-w option is given a
whitelist *package*.
* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt:
New test output reference.
* tests/test-diff-pkg.cc (in_out_spec): Compare
data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64.rpm and
data/test-diff-pkg/spice-server-0.12.8-1.el7.x86_64.rpm with the
new --leaf-changes-only and --impacted-interfaces options, using
the new output reference above.
* tests/data/Makefile.am: Add the new test material to source
distribution.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch allows abidiff to take the --leaf-changes-only option and
then to display only the changes that are local to any given type.
That means the reporting agent won't follow pointers when displaying
changes. That gives less context to the ABI change reports but then
they are less cluttered.
To do this, the patch introduces a new reporting agent to libabigail:
abigail::comparison::leaf_reporter. When given a graph of diff nodes,
this agent only reports about the leaf (local) changes. That is, it
will *NOT* follow pointers, references, underlying types of qualified
and typedef types and things like that. It will just report about
changes that are local to a given type.
This reporting agent is then used (in lieu of the default
abigail::comparison::default_reporter agent) when the
--leaf-changes-only option is provided by the user on the command line
of abidiff.
Note that abidiff also takes the --impacted-interfaces option to so
that the leaf reporter shows the set of interfaces impacted
by each leaf change.
* doc/manuals/abidiff.rst: Add documentation the new
--leaf-changes-only and --impacted-interfaces options.
* src/abg-leaf-reporter.cc: New file.
* src/Makefile.am: Add the new src/abg-leaf-reporter.cc file to
source distribution.
* include/abg-fwd.h (get_var_size_in_bits)
(function_decl_is_less_than): Declare new functions.
(get_name): Add new overload for type_or_decl_base*.
* include/abg-ir.h (struct type_or_decl_hash, type_or_decl_equal)
(type_or_decl_base_comp): Define new types.
(artifact_sptr_set_type, artifact_ptr_set_type): Define new
typedefs.
* include/abg-comp-filter.h: Update copyright year.
(has_basic_type_name_change): Add new function declaration.
* src/abg-comp-filter.cc (decl_name_changed): Take a
type_or_decl_base rather than just a decl. Add an overload for
diff*.
(has_basic_type_name_change): Define new function.
* include/abg-comparison.h: Update copyright year.
(string_diff_ptr_map): Define this new typedef.
(class diff_maps): Define this new class.
(diff_context::{set_corpora}): Remove this member function.
(diff_context::{set_corpus_diff, get_corpus_diff,
show_leaf_changes_only, show_impacted_interfaces,
forbid_visiting_a_node_twice_per_interface}): Declare these new
member functions.
(diff_node_visitor::priv_): Add a new pimpl data member.
(diff_node_visitor::{diff_node_visitor, get_visiting_kind,
set_visiting_kind}): Turn these into out-of-line member functions.
(diff_node_visitor::{set,get}_current_topmost_iface_diff): Add new
member functions.
(class {scope_diff, function_type_diff, corpus_diff}): Add class
leaf_reporter as a friend.
(corpus_diff::mark_leaf_diff_nodes, get_leaf_diffs): Declare new
member functions.
(diff::{visiting_a_node_twice_is_forbidden_per_interface,
parent_interface_node}): Define new member functions.
(is_diff_of_basic_type): Return a type_decl_diff* rather than just
a bool.
(is_enum_diff, is_array_diff, is_function_type, is_typedef_diff)
(is_corpus_diff): Declare new functions.
(corpus_diff::diff_stats::{num_leaf_changes,
num_leaf_changes_filtered_out, net_num_leaf_changes}): Add new
member functions.
(is_distinct_diff): Declare new function.
* include/abg-reporter.h: Forward-declare "class diff_maps".
(reporter_base::diff_to_be_reported): Declare a new virtual member
function.
(reporter_base::{report_local_typedef_changes,
report_local_reference_type_changes,
report_local_function_type_changes}): Declare new member
functions.
(class leaf_reporter): Define new type.
* src/abg-comparison-priv.h (struct diff_hash, diff_equal): Define
new types.
(diff_artifact_set_map_type): Define new typedef.
(diff_context::priv::{first_corpus_, second_corpus_}): Remove
these data members.
(diff_context::priv::{corpus_diff_, leaf_changes_only_,
reset_visited_diffs_for_each_interface_,
show_impacted_interfaces_}): Add new data members.
(diff_context::priv::priv): Adjust.
(corpus_diff::priv::{leaf_diffs_, parent_interface_}): Add new
data member.
(corpus_diff::diff_stats::priv::{num_leaf_changes,
num_leaf_changes_filtered_out}): Add new data members.
(corpus_diff::priv::count_leaf_changes): Define new member
function.
(sort_artifacts_set, get_fn_decl_or_var_decl_diff_ancestor)
(is_diff_of_global_decls): Declare new functions.
(function_comp::operator()): Factorize this out into the new
function abigail::ir::function_decl_is_less_than.
* src/abg-ir.cc (get_var_size_in_bits)
(function_decl_is_less_than): Define new functions.
(get_name): Define new overload for type_or_decl_base*.
* src/abg-comparison.cc (is_enum_diff, is_typedef_diff)
(is_array_diff, is_function_type_diff, is_corpus_diff)
(is_distinct_diff, sort_artifacts_set, is_diff_of_global_decls):
Define new functions.
(is_union_diff): Fix comment.
(diff_context::forbid_visiting_a_node_twice_per_interface): Define
new member functions.
(diff_context::set_corpus_diff, get_corpus_diff)
(diff_context::show_leaf_changes_only)
(diff_context::visiting_a_node_twice_is_forbidden_per_interface)
(diff_context::show_impacted_interfaces): Define new member
functions.
(diff_context::get_reporter): Create the reporter that matches
what diff_context::show_leaf_changes_only says.
(diff_node_visitor::priv): Define a new type.
(diff_node_visitor::{diff_node_visitor, get_visiting_kind,
set_visiting_kind, or_visiting_kind,
set_current_topmost_iface_diff, get_current_topmost_iface_diff}):
Define new out-of-line member functions.
(struct diff_maps::priv): Define new type.
(diff_maps::{diff_maps, get_type_decl_diff_map,
get_type_decl_diff_map, get_enum_diff_map, get_class_diff_map,
get_union_diff_map, get_typedef_diff_map, get_array_diff_map,
get_function_type_diff_map, get_function_decl_diff_map,
get_var_decl_diff_map, get_reference_diff_map,
get_fn_parm_diff_map, get_distinct_diff_map, insert_diff_node,
lookup_impacted_interfaces}): Define member functions.
(corpus_diff::{mark_leaf_diff_nodes, get_leaf_diffs}): Define new
member functions.
(struct leaf_diff_node_marker_visitor): Define new type.
(corpus_diff::apply_filters_and_suppressions_before_reporting):
Mark diff nodes in here.
(corpus_diff::traverse): Appropriately set the current topmost
interface into the visitor before visiting a diff node.
(compute_diff): In the overload for corpus_sptr, adjust to reflect
that we are now storing the corpus_diff in the diff context.
(is_diff_of_basic_type): Return a type_decl_diff*, not just a
bool.
(corpus_diff::priv::count_leaf_changes): Define a new member
function.
(corpus_diff::diff_stats::{num_leaf_changes,
num_leaf_changes_filtered_out, net_num_leaf_changes}): Define new
member functions.
(corpus_diff::priv::apply_filters_and_compute_diff_stats): Use the
new corpus_diff::priv::count_leaf_changes to compute the number of
leaf changes.
(corpus_diff::priv::emit_diff_stats): Emit the report about leaf
type changes when necessary.
* src/abg-reporter-priv.h (report_mem_header): Declare new
overload.
(maybe_show_relative_offset_change,): Pass the var_diff_sptr
parameter by const reference.
(represent): Pass the var_diff_sptr parameter by const reference
and take a new "local-only" flag.
(maybe_show_relative_size_change)
(maybe_report_interfaces_impacted_by_diff): Declare new functions.
* src/abg-default-reporter.cc: Adjust copyright year.
(default_reporter::{report_local_typedef_changes,
report_local_qualified_type_changes,
report_local_reference_type_changes,
report_local_function_type_changes}): Define new member functions.
(default_reporter::report): Adjust. Add an overload for
function_type_diff&. In the overload for qualified_type_diff, if
the name of the underlying type changed, do not detail the changes
any further. In the overload for function_decl_diff, Adjust to
use the new diff_context::get_{first, second}_corpus member
function. In the overload for enum_diff, call the new
maybe_report_interfaces_impacted_by_diff that is advertised below.
* src/abg-reporter-priv.cc (represent): Adjust the overload for
var_diff_sptr.
(report_mem_header): Define new overload.
(maybe_show_relative_size_change)
(maybe_report_interfaces_impacted_by_diff): Define new functions.
(reporter_base::diff_to_be_reported): Define new member function.
(maybe_show_relative_offset_change): Pass the var_diff_sptr
parameter by const reference.
(represent): In the overload for var_diff_sptr, pass the
var_diff_sptr parameter by reference. Take a 'local_only' flag.
Iisplay type changes only if we are not displaying "local changes
only". Display size changes of data members too, when in
"local-only" mode.
* src/abg-suppression.cc (sonames_of_binaries_match)
(names_of_binaries_match): Adjust.
* tools/abidiff.cc (options::{leaf_changes_only,
show_impacted_interfaces}): Add new data members.
(display_usage): Emit usage string for the new --leaf-changes-only
and --impacted-interfaces options.
(parse_command_line): Parse the new --leaf-changes-only and the
--impacted-interfaces options.
(set_diff_context_from_opts): Set the 'show-leaf-changes' and the
'show-impacted-interfaces' flags.
* tests/data/test-diff-filter/libtest42-leaf-report-v{0,1}.so: New
test input.
* tests/data/test-diff-filter/test42-leaf-report-output-0.txt: New
test reference output.
* tests/data/test-diff-filter/test42-leaf-report-v{0,1}.cc: Source
code of the new test inputs.
* tests/test-diff-filter.cc (in_out_specs): Use the new test
inputs above in this harness.
* tests/data/test-diff-suppr/libtest35-leaf-v0.so: New test input.
* tests/data/test-diff-suppr/test35-leaf-report-0.txt: New test
reference output.
* tests/data/test-diff-suppr/test35-leaf-v{0,1}.cc: Source code of
the new test inputs.
* tests/data/test-diff-suppr/test35-leaf.suppr: Suppression
specification to use for the test35 test.
* tests/data/test-diff-suppr/libtest36-leaf-v0.so: New test input.
* tests/data/test-diff-suppr/libtest36-leaf-v1.so: Likewise.
* tests/data/test-diff-suppr/test36-leaf-report-0.txt: New
reference test output.
* tests/data/test-diff-suppr/test36-leaf-v0.cc: Source code of
test input above.
* tests/data/test-diff-suppr/test36-leaf-v1.cc: Likewise.
* tests/test-diff-suppr.cc (in_out_specs): Use the new test inputs
above in this harness.
* tests/data/Makefile.am: Add the new test inputs above to source
distribution.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Right now, the reporting functionnality is implemented directly in the
comparison engine. Being able to emit several kinds of reports is
really not practical with the current design.
This patch improves that situation by introducing an indirection
between the comparison engine and the code that emits the report.
A new abigail::comparison::reporter_base type is introduced. That
type several contains virtual methods that knows how to implement
reporting. Each virtual method reports about changes carried by a
kind of diff node. In other words, abigail::comparison::reporter_base
is the interface of reporter objects.
The current reporting using the current format is thus implemented by
the new abigail::comparison::default_reporter type, which implements
the abigail::comparison::reporter_base interface.
The diff::report methods now "just" get the reporter object from the
context of the diff and invoke its right reporting interface.
So whenever someone needs to implement a new reporting format, she
needs to provide a new implementation of the
abigail::comparison::reporter_base interface and set it to the
diff_context prior to invoking the
abigail::comparison::corpus_diff::report() method.
* include/Makefile.am: Add the new abg-reporter.h header file to
source distribution.
* include/abg-comparison.h: Include the new abg-reporter.h header
file.
(diff_context::{g,s}et_reporter): Declare new accessors.
({type_diff_base, decl_diff_base, corpus_diff}::priv): Make this
be a struct rather than a class.
({decl_diff_base, class_diff, scope_diff, function_type_diff,
corpus_diff}): Declare default_reporter a friend class of these.
* include/abg-reporter.h: New file.
* src/Makefile.am: Add abg-comparison-priv.h,
abg-reporter-priv.{h,cc} and abg-default-reporter.cc files to
source distribution.
* src/abg-comparison-priv.h: New file.
* src/abg-comparison.cc (sort_enumerators)
(sort_changed_enumerators, sort_data_members)
(sort_string_function_ptr_map)
(sort_string_function_decl_diff_sptr_map)
(sort_string_var_diff_sptr_map, sort_string_elf_symbol_map)
(sort_string_var_ptr_map, sort_string_data_member_diff_sptr_map)
(sort_unsigned_data_member_diff_sptr_map)
(sort_string_diff_sptr_map, sort_string_base_diff_sptr_map)
(sort_string_base_sptr_map, sort_string_fn_parm_diff_sptr_map)
(sort_string_parm_map, get_leaf_type, sort_enumerators)
(sort_changed_enumerators): Make these functions non-static and
move them at the beginning of the file. These functions are now
declared in abg-compared-priv.h so they can be shared privately
with other files in src/.
(diff_context::{g,s}et_reporter): Define new accessors.
({diff_context, diff, type_diff_base, decl_diff_base,
distinct_diff, pointer_diff, array_diff, reference_diff,
qualified_type_diff, enum_diff, class_or_union_diff, class_diff,
base_diff, scope_diff, fn_parm_diff, function_type_diff,
function_decl_diff, type_decl_diff, typedef_diff,
translation_unit_diff, corpus_diff::diff_stats,
corpus_diff}::priv)
(diff_less_than_functor, enumerator_value_comp)
(changed_enumerator_comp, base_spec_comp, base_diff_comp)
(data_member_diff_comp, diff_comp, fn_parm_diff_comp, parm_comp)
(elf_symbol_comp, function_comp, function_decl_diff_comp)
(var_diff_sptr_comp): Move these type definitions to
abg-comparison-priv.h
(report_size_and_alignment_changes, report_loc_info)
(maybe_report_diff_for_member, maybe_report_diff_for_symbol)
(represent, represent_data_member)
(maybe_show_relative_offset_change, represent)
(report_size_and_alignment_changes, report_loc_info)
(report_name_size_and_alignment_changes, report_mem_header)
(maybe_report_diff_for_member, maybe_report_diff_for_symbol)
(show_linkage_name_and_aliases): Move these definitions to
abg-reporter-priv.cc.
({distinct_diff, var_diff, pointer_diff, array_diff,
reference_diff, qualified_type_diff, enum_diff,
class_or_union_diff, class_diff, base_diff, union_diff,
scope_diff, fn_parm_diff, function_type_diff, type_decl_diff,
typedef_diff, corpus_diff}::report): Use the reporter object to
report about the changes carried by the the current diff node.
* src/abg-default-reporter.cc: New file.
* src/abg-reporter-priv.h: Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-writer.cc (write_context::m_emitted_decl_only_set):
Renamed m_emitted_decl_only_map into this and make the type be a
set, rather than a map.
(write_context::{record_decl_only_type_as_emitted,
decl_only_type_is_emitted}): Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
To record the emitted types, the abixml writer records the emitted
type *ID*s. So to lookup an emitted type, it needs to lookup the ID
of the type first, and then lookup that type-id in the set of emitted
type IDs. We are doing twice as much work as we should and profiling
the writting of a big abixml showed that it's quite taxing.
This patch makes the write records the set of emitted types directly.
No need to go through the emitted type *ID*s anymore. So we save one
map lookup. This incurs a 16% speedup when writting an abixml file
for a big (3GB) vmlinux file.
* src/abg-writer.cc (type_ptr_set_type): Declare new typedef.
(writer_context::m_emitted_type_id_map): Remove this data member.
(writer_context::m_emitted_type_set): Add a new data member.
(writer_context::{record_type_id_as_emitted, type_id_is_emitted,
clear_emitted_types_map}): Remove these member functions.
(writer_context::{record_type_as_emitted, type_is_emitted}): Use
the new m_emitted_type_set data member above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Until now, the canonical DIE offsets map (the map that associates a
canonical DIE offset to a given DIE offset) was implemented in the
DWARF reader by using vectors. This proves to use a lot of memory
(more than 25GB!!) for huge vmlinux binaries. So much that the thing
was too slow (hey, yeah, because it was swapping out!) on vmlinux
kernel binary of 3GB of size, just to abidw it out.
This patch changes that to use an unordered map for this. It now uses
~ 4GB of peak RAM memory, so I can actually abidw the vmlinux of 3GB
of size on my laptop. It's still taking 16 minutes (!!) to complete,
but at least it's progress, as it's completed at least, without
swapping out.
And it doesn't see to noticeably slowdown the test suite.
* src/abg-dwarf-reader.cc
(read_context::canonical_type_die_offsets_): Renamed the
canonical_type_die_vecs_ data member into this.
(read_context::canonical_decl_die_offsets_): Renamed the
canonical_decl_die_vecs_ data member into this.
(read_context::{initialize, compute_canonical_die_offset,
compute_canonical_die, get_canonical_die,
get_or_compute_canonical_die, set_canonical_die_offset,
get_canonical_die_offset}): Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When computing a canonical DIE while reading DWARF, we crash in
get_or_compute_canonical_die basically because we loop over a vector
using an iterator which gets invalidated during the walk because some
code in the loop can increase the size of the vector (by adding
elements at its end) during the loop.
This patch fixes the issue by looping over the vector without using an
iterator that can be invalidated. The code now properly expects the
vector to grow during the walk.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-dwarf-reader.cc (dwarf_offsets_type): There are two
instances of this typedef declaration, remove one.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
While looking into something else, I realized that for consistency,
the name of the offset_offset_map type should be
offset_offset_map_type. So I just did the change.
* src/abg-dwarf-reader.cc (offset_offset_map_type): Renamed
offset_offset_map into this.
(read_context::{primary_die_parent_map_,
alternate_die_parent_map_, type_section_die_parent_map_}): Adjust
the type of these data members.
(read_context::{die_parent_map, type_section_die_parent_map}):
Adjust the type of these member functions.
(read_context::{build_die_parent_relations_under,
get_parent_die}): Adjust for the type name in these functions.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch initializes the annotate state flag in abidw. Oops.
* tools/abidw.cc (options::options): Initialize the annotate data
member.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When comparing classes that differ in their number of virtual member
functions, it can happen that we crash because we should have got out
earlier.
This patch fixes that. That problem happens on the test provided in
PR libabigail/17948 -- which is too big to be included in the test
suite.
* src/abg-ir.cc (equals): In the overload for class_decl, when we
detect that the virtual member function counts are different, get
out, even when we are being asked about the kind of the change.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When we face two equivalent highly recursive structs/classes, it can
happen that a given data member be added twice to the type. When
comparing two versions of a binary in which the data member happens to
have been removed from the second version, we thus trigger an assert
because a given data member has been "removed twice".
This happens on the example provided in PR libabigail/17948 -- which
is too big to be added to the test suite.
This patch hopefully fixes the issue by looking harder at the data
structure to make sure that we don't add the same data member twice.
* src/abg-dwarf-reader.cc (add_or_update_class_type): After a we
try to create a data member type, look *again* if the data member
wasn't added recursively by the creation of the data member type.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch makes the data_member_diff_comp comparison functor consider
all the properties local to the data member: that is, its offset and
its name.
It used to only take the offset into account.
This makes sure that offset change reports have a stable ordering and
thus makes the runtestdiffpkg testcase succeeds on debian-i386.
* src/abg-comparison.cc (data_member_diff_comp): Make the
comparison take the qualified name of the data member into
account. Also, if the initial offset and qualified names of the
data members of the diff nodes are equal, consider the offset and
qualified names of the new data members.
Signed-off-by: Mark Wielaard <mark@klomp.org>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When computing canonical DIEs, the DWARF reader mistakenly represents
'array of const' and 'const array' the same.
This patch fixes that.
* src/abg-dwarf-reader.cc (die_is_array_type): Define new static
function.
(die_is_pointer_or_reference_type): Also test that the DIE can be
an array.
* tests/data/test-read-dwarf/PR22122-libftdc.so: New binary test input.
* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: New reference output.
* tests/data/Makefile.am: Add the two new test files above to
source distribution.
* tests/test-read-dwarf.cc (in_out_specs): Run this test harness
over the new test input.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When the size of a var_decl changes, we want the 'equals' function for
var_decl to report that change as being a local one, not a subtype
one.
This patch fixes that.
* src/abg-ir.cc (equals): In the var_decl overload detect size
changes of type as being a local change.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Since glibc 2.24 readdir_r() is deprecated.
Applications are recommended to use readdir which is thread-safe when
using different directory streams (we explicitly create a new one here).
* src/abg-tools-utils.cc (dir_is_empty): Use readdir() instead
of readdir_r().
Signed-off-by: Mark Wielaard <mark@klomp.org>
On 32bit platforms [s]size_t isn't the same as [u]int64_t causing:
abg-dwarf-reader.cc:358:1: warning: ‘bool abigail::dwarf_reader::eval_last_constant_dwarf_sub_expr(Dwarf_Op*, size_t, ssize_t&, bool&)’ declared ‘static’ but never defined [-Wunused-function]
* src/abg-dwarf-reader.cc (eval_last_constant_dwarf_sub_expr):
Declare expr_len as uint64_t and value as int64_t.
Signed-off-by: Mark Wielaard <mark@klomp.org>
During DWARF reading, it can happen that we want to get the global
scope of a DIE which translation unit hasn't yet been constructed.
In that case, use the global scope of the current translation unit.
* src/abg-dwarf-reader.cc (get_scope_for_die): If the translation
unit of the parent die hasn't yet been constructed, then return
the global scope of the current translation unit.
* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so: New
binary test input.
* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
New reference test output.
* tests/data/Makefile.am: Add the new test materials above to
source distribution.
* tests/test-read-dwarf.cc (in_out_specs): Add the new test input
to the test suite.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Apparently we forgot to add some test input files to the source
distribution.
Fixed thus.
* tests/data/Makefile.am: Add
test-diff-dwarf/test42-PR21296-libgcc.so,
test-diff-dwarf/test42-PR21296-libclang.so,
test-diff-dwarf/test42-PR21296-clanggcc-report0.txt to the source
distribution. Also look for test-diff-filter/test39* tests inputs
in the test-diff-filter/test39/ directory.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When for a reason the ELF file could not be read and yet the user
keeps going with the elf reader context, it can happen that we crash.
This patch fixes that.
* src/abg-dwarf-reader.cc
(read_context::elf_architecture_is_ppc64): Do not crash if the elf
handle is nil.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This is the initial patch that makes abipkgdiff recognize Linux kernel
packages passed in argument and do the right thing.
abipkgdiff gets the vmlinux binary from the debug info package,
considers the union of that vmlinux binary and the thousands of kernel
modules that we shall name "the Kernel". It then compares ABI
(actually Kernel/Module Interface, a.k.a KMI) of the Kernel of the
first package against the KMI of the Kernel of the second package.
* include/abg-tools-utils.h (get_vmlinux_path_from_kernel_dist):
Declare new function.
(get_binary_paths_from_kernel_dist): Re-organize order of
parameters.
(file_is_kernel_package, file_is_kernel_debuginfo_package): Make
the file_path parameter be const.
(build_corpus_group_from_kernel_dist_under): Take an additional
debug_info_root parameter.
* src/abg-tools-utils.cc (file_is_kernel_package)
(file_is_kernel_debuginfo_package): Const-ify the file_name
parameter.
(find_vmlinux_path): Define new static function.
(get_binary_paths_from_kernel_dist): Re-organize the order of
parameters. The debug_info_root_path parameter is now an input
parameter.
(get_vmlinux_path_from_kernel_dist): Define new function.
(get_binary_paths_from_kernel_dist): Adjust invocation of
get_binary_paths_from_kernel_dist.
(build_corpus_group_from_kernel_dist_under): Take an additional
debug_info_root parameter.
* tools/abidw.cc (load_kernel_corpus_group_and_write_abixml):
Adjust invocation to build_corpus_group_from_kernel_dist_under.
* tools/abipkgdiff.cc (create_maps_of_package_content): Don't map
the content of a Linux Kernel package.
(compare_prepared_userspace_packages)
(compare_prepared_linux_kernel_packages, compare_prepared): Define
new functions.
(compare): Use the new functions above here.
* tools/kmidiff.cc (print_kernel_dist_binary_paths_under): Adjust
the invocation of get_binary_paths_from_kernel_dist.
(main): Adjust the invocation of
build_corpus_group_from_kernel_dist_under. Make sure that a
kernel package is accompanied by a debug info package.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
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>