Profiling showed that getting the pointed-to type of a pointer type is
on the hot spot when comparing corpora with a lot of entry points with
a lot of pointer types reachable from the entry points of the corpora.
So avoid handling the shared_ptr to the pointed-to type for that case
can save us a few CPU cycles in a noticeable way.
This patch does this by creating a new
pointer_type_def::get_naked_pointed_to_type() (that returns a naked
pointer) to supplement the classic
pointer_type_def::get_pointer_to_type() function, and uses that in a
code spot that profiling revealed to be a critical path.
* include/abg-ir.h (pointer_type_def::get_naked_pointed_to_type):
Declare new member function.
* src/abg-ir.cc (pointer_type_def::priv::naked_pointed_to_type_):
New data member.
(pointer_type_def::priv::priv): Adjust to initialize the new data
member.
(pointer_type_def::pointer_type_def): Adjust to use the
constructor pointer_type_def::priv::priv to initialize the
pointed-to type (including its new naked pointer variant). So we
do not have to initialize the priv_->pointed_to_type_ explicitely
in the constructor anymore.
(pointer_type_def::get_naked_pointed_to_type): Define new data
member.
(pointer_type_def::get_qualified_name): Use a naked pointer to the
pointed-to type, rather than a smart pointer.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Profiling shows that some smart pointers were unnecessarily created
here and there, and that had a noticeable effect on performance, when
comparing two gtk3 packages.
This patch passes references to smart pointers in those cases.
* include/abg-fwd.h (get_type_name): Take a reference to type_sptr.
* src/abg-ir.cc (get_type_name): Take a reference to type_sptr.
(suppression_base::priv::{get_file_name_regex,
get_file_name_not_regex, get_soname_regex, get_soname_not_regex}):
Return a reference to regex_t_sptr.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Profiling showed that abigail::tools_utils::string_ends_with can be
quite a hot spot when evaluating suppression specifications that
involve file names in the source location of definition of files.
In that function, it appears that we were calling string::length
several times on the same strings. Calling it just once does make a
noticeable difference when type suppressions involving source
locations are evaluated against a lot of types.
This patch thus calls string::length in
abigail::tools_utils::string_ends_with just once.
* src/abg-tools-utils.cc (string_ends_with): Call string::length
just once on each instance of string that matters.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When evaluating type suppression specifications, looking at the name
of the type can take a noticeable time, at least when the name of that
type is being queried for the first time.
Now that every single type involved in a change that might be reported
is involved in a type suppression evaluation (at least when operating
in the mode where the comparison tool is asked to filter out private
types), the evaluation of type suppression becomes a hot spot, at
least on relatively big diff graphs.
Luckily, private type suppression specifications don't involve the
name of the type, so we don't have to query the name of the type in
this case.
This patch makes it so that the type name is queried only when the
suppression specification requires it. It makes us save a few
noticeable CPU cycles when evaluating suppression specifications that
don't involve looking at the type name.
* src/abg-suppression.cc (type_suppression::suppresses_type): If
neither the type suppression "name" or "name_regex" properties
where provided in the suppression specification, then do not try
to look at the type name.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
On certain work loads, cycles in the tree of diffs of member variables
can appear. This because:
1/ each diff tree nodes holds a reference on each of its children
nodes
2/ each var_diff tree node holds a reference on the diff tree node
representing its type changes.
There can thus be reference cycles in involving diff the tree --> child
node relationship and the var_diff tree --> type diff tree
relationship.
This patch fixes the issue be make sure that a diff tree node does not
hold a reference on its children nodes. That is, rather than having a
vector of shared pointers to its children diff nodes, it has a vector
of naked pointers to those. The patch goes further by making sure
that a var_diff node does not hold a reference to its type diff node
either. It holds a weak pointer to the type diff node, rather than a
shared pointer.
The patch should be followed by a patch make sure that all kinds of
diff nodes follow this pattern; that is, if a diff node needs to carry
a sub-type diff node, it should do so by either using a naked pointer
to the sub-type diff node, or a weak pointer.
For now, the patch fixes the leaks reported by running all the tests
of the suite under Valgrind.
* include/abg-comparison.h (diff_wptr, unordered_diff_sptr_set): New typedefs.
(struct diff_sptr_hasher): Define new type.
(diff_context::keep_diff_alive): Declare new member function.
(diff::children_nodes): Return a vector of diff*, rather than a
vector of diff_sptr.
* src/abg-comparison.cc (diff_context::priv::live_diffs_): New
data member.
(diff_context::keep_diff_alive): Define new data member.
(diff::priv::children_): Make this be a vector of diff*, rather
than a vector of diff_sptr.
(diff_less_than_functor::operator()): Add a new overload for
diff*. Make the existing overload of diff_sptr use the new one.
(diff::children_nodes): Adjust;
(diff::append_child_node): Make sure the child node is kept
alive. Only add the naked pointer to the child node to the vector
of children.
(diff::traverse): Adjust.
(var_diff::priv::type_diff_): Make this be a weak pointer, rather
than a shared pointer.
(var_diff::type_diff): The var_diff::priv::type_diff_ data member
is now a weak pointer, so make this accessor convert it to a
shared pointer.
(corpus_diff::priv::children_): Turn this into a vector of diff*,
rather than a vector of diff_sptr.
(corpus_diff::children_nodes): Adjust.
(corpus_diff::append_child_node): Make sure the child node is kept
alive. Only add the naked pointer to the child node to the vector
of children.
(category_propagation_visitor::visit_end): Adjust.
(suppression_categorization_visitor::visit_end): Adjust.
(redundancy_marking_visitor::{visit_begin, visit_end}): Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Diff not chilrend nodes must remain sorted. Before this patch, this
was achieved by sorting the vector of children each time a new member
was inserted.
But profiling showed that doing that for corpus_diff nodes was
relatively slow on corpora with lots function/variable changes. At
least enough to become a hot spot.
This patch addresses that by inserting the new child at the right
point in the vector of children, for the vector to remain sorted.
* src/abg-comparison.cc (corpus_diff::append_child_node): Insert
the new child at the right point in the vector of children, so
that it remains sorted.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
On recent elfutils where the libdw's function dwarf_getalt exists, we
don't need to try and find the alternate debug info file ourselves by
using the function dwfl_standard_find_debuginfo. Furthermore, when we
use that function on those recent elfutils versions, we leak the elf
resources allocated in the debug info resources; we also leak the file
descriptor to access the alternate debug info sections.
More generally, we also leak debug info handles used to access debug
info when using get_soname_of_elf_file and get_type_of_elf_file.
This patch plugs those leaks.
In the first case, if the function dwarf_getalt exists, the patch just
uses it to get the alternate debug info. Otherwise, the patch uses
the dwfl_standard_find_debuginfo function like we used to, but then it
tries hard to free the file descriptor and debuginfo memory of the
alternate debug info.
* configure.ac: Check the presence of dwarf_getalt in libdw. If
it's present, define the preprocessor macro
LIBDW_HAS_DWARF_GETALT. Update the autoconf configuration
summary.
* src/abg-dwarf-reader.cc: Add config.h.
(find_alt_debug_info_location): Factorize this out of ...
(find_alt_debug_info): ... this function. Use dwarf_getalt if
present, otherwise, keep using dwfl_standard_find_debuginfo. In
the later case, return the file descriptor opened to access the
alternate debug info, by parameter, so that the caller can fclose
it.
(read_context::alt_fd_): New data member.
(read_context::read_context): Initialize the new alt_fd_ data
member.
(read_context::load_debug_info): Store the file descriptor used to
access the alternate debug info into the new alt_fd_ data member.
(read_context::~read_context): New desctructor.
(get_soname_of_elf_file, get_type_of_elf_file): Free the elf
handle.
(read_context::load_debug_info): Be paranoid in making sure we
never override alt_dwarf_.
* tests/data/test-alt-dwarf-file/test0-report.txt: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Some time ago, a memory optimization was put in place to reduce the
memory usage of the IR used to represent the result of a comparison
between two corpora.
The principle of that optimization was to share the data of the
class_diff::priv member among instances of class_diff that are in the
same class of equivalence.
In practice, the class_diff::priv member of an instance that has a non
empty class of equivalence was set to the class_diff::priv of its
canonical type.
Because clas_diff::priv is a shared pointer, setting it to the
class_diff::priv of another instance was creating cycles in the graph
of class_diff, sometimes. And those cycles lead to memory leaks as
the reference count of shared pointers to class_diff would not go down
to zero anymore.
This patch fixes the problem of those cycles by not setting the
class_diff::priv data member. Rather, when a class_diff is part of a
non-empty class of equivalence, its class_diff::priv is left nil. A
new class_diff::get_priv() accessor is provided; it returns the shared
class_diff::priv of the canonical type when the current
class_diff::priv is nil; otherwise it just returns the current
class_diff::priv.
* include/abg-comparison.h (class_diff::get_priv): Declare new
member function.
(class_diff::get_priv): Define new member function.
(class_diff::{chain_into_hierarchy, base_changes, deleted_bases,
inserted_bases, changed_bases, base_changes, member_types_changes,
member_types_changes, data_members_changes, inserted_data_members,
deleted_data_members, member_fns_changes, changed_member_fns,
member_fns_changes, deleted_member_fns, inserted_member_fns,
member_fn_tmpls_changes, member_class_tmpls_changes,
member_class_tmpls_changes, report}): Rather than accessing
class_diff::priv directly, use the new class_diff::get_priv.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
It appears that there are cases where the data member
class_decl::priv::definition_of_declaration_ can point to the current
instance of class_decl, leading to a circular reference and thus a
leak because the reference count of the current instance of class_decl
will never reach zero.
This patch fixes that by making
class_decl::priv::definition_of_declaration_ be a weak pointer, rather
than a smart pointer.
* include/abg-ir.cc (class_decl::get_definition_of_declaration):
Return a shared pointer, rather than a reference to a shared pointer.
* src/abg-ir.cc (class_decl::priv::definition_of_declaration_):
Make this be a weak pointer.
(class_decl::get_definition_of_declaration):
Likewise. And return the shared pointer built out of the weak
pointer we have in there now.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The suppression engine was not creating the shared pointer to
regex_t in the proper way that would correctly free the memory
allocated by the glibc's regcomp function.
This patch fixes that.
* include/abg-sptr-utils.h (build_sptr<T>): Declare an overload that
allocates a T* and wraps it into a shared_ptr<T>.
(build_sptr<regex_t>): Declare a specialization for regex_t.
* src/abg-corpus.cc (build_sptr<regex_t>()): Define the
specialization here.
* src/abg-suppression.ccp
(suppression_base::priv::{get_file_[not]_name_regex,
get_soname_[not]_regex}): Use the new build_sptr<regex_t>().
(type_suppression::priv::{get_type_name_regex,
get_source_location_to_keep_regex}): Likewise.
(function_suppression::parameter_spec::priv::get_type_name_regex):
Likewise.
(function_suppression::priv::{get_name_regex,
get_return_type_regex, get_symbol_name_regex,
get_symbol_version_regex}): Likewise.
(variable_suppression::priv::{get_name_regex,
get_symbol_name_regex, get_symbol_version_regex,
get_type_name_regex}): Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
After the function compute_diff is invoked to compute the diff against
to corpora, the reference count of the diff_context_sptr that it takes
get incremented several times.
So the diff_context_sptr is not automatically released (freed) when
its scope is left.
The reason why the reference count of diff_context_sptr is incremented
is because several diff types (the diff type itself or types extending
it) actually holds a reference to the diff_context_sptr they get
created with. So the lifetime of the diff_context_sptr becomes tied
to the lifetime the different diff objects in a hard-to-predict way.
It actually creates some cyclic references that, in this case, creates
a leak. The diff_context_sptr never gets released.
This patch fixes that by making the diff types hold a weak reference
to the diff_context_sptr they are created with.
* src/abg-comparison.cc (diff::priv::ctxt_): Make this a weak_ptr.
(diff::priv::get_context): Convert the weak pointer to the context
into a shared_ptr and return it.
(diff::priv::is_filtered_out): Adjust to use
diff::priv::get_context() to access the context.
(diff::context): Likewise.
(corpus_diff::priv::ctxt_): Make this a weak_ptr.
(corpus_diff::priv::priv): Add a new overload that takes two
corpora and a diff context.
(corpus_diff::priv::get_context): Convert the weak pointer to the
context into a shared_ptr and return it.
(corpus_diff::priv::ensure_lookup_tables_populated): Adjust to use
the new corpus_diff::priv::get_context to get the context.
(variable_is_suppressed): Likewise.
(corpus_diff::priv::{apply_suppressions_to_added_removed_fns_vars,
apply_filters_and_compute_diff_stats, emit_diff_stats,
categorize_redundant_changed_sub_nodes,
clear_redundancy_categorization}): Likewise.
(corpus_diff::{corpus_diff, context,
apply_filters_and_suppressions_before_reporting}): Adjust.
* tools/abipkgdiff.cc (compare): Make the overload that compares
elf binaries take a diff context output parameter. After the
context is created by this function, it's return to the caller, so
that it's life time is bound to the scope this function was
called from.
(pthread_routine_compare): Create a shared pointer to hold a
reference on a diff context. Pass that shared pointer by
reference to the compare function that compares elf binaries.
Rather than storing corpora in the reports_map, (as those corpora
would then out-live the diff context and thus create memory
corruption issues), emit the report directly into an ostringstream
and store that stream in reports_map.
(compare): In the overoad that compares packages, rather than
trying to get corpora from the report_map, just emit the content
of the ostringstream that is now there.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When reading in an array of the GNU ELF hash table, we read one
integer right after the end of the array.
This patch fixes that.
* src/abg-dwarf-reader.cc (lookup_symbol_from_gnu_hash_tab): Do
not read passed the end of the array.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch allows maintainers to run:
make -C <builddir>/tests check-valgrind
This runs the test suite under the Valgrind memory checker.
It also adds this target:
make -C <builddir>/tests check-valgrind-memcheck-recursive
It runs the memcheck tool on the tests so that programs forked by them
are memchecked too. This is to allow to memcheck the libabigail tools
that are forked by the individual tests.
* autoconf-archive/ax_valgrind_check.m4: Add new file. Copied it
from http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html.
* configure.ac: Include the new ax_valgrind_check.m4 file.
Initialize the valgrind checking on tests. Update the configure
status.
* tests/test-valgrind-suppressions.supp: New valgrind suppression
file to silence memcheck leak errors from python.
* tests/Makefile.am: Add test-valgrind-suppressions.supp to source
distribution. Add check-valgrind-memcheck-recursive target.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Explain how ChangeLog entries need to refer to each modified
function. Also, give more information more about the expected spirit
of the commit log.
* COMMIT-LOG-GUIDELINES: Various enhancements.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Positional argument specifiers can be omitted for example '{} {}'. This
is introduced in Python 2.7. Not sure if fedabipkgdiff would be used by
someone with Python 2.6, anyway using consistent string format is a good
way.
* tools/fedabipkgdiff (download_rpm): do not omit positional
argument specifiers in string format.
Signed-off-by: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This is an autogenerated file, it has nothing to do in the repository.
* config.h.in: Remove from repository.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
fedabipkgdiff is a convenient way to compare the ABI of Fedora
packages easily.
The first version of fedabipkgdiff introduced by this patch lets users
perform operations like:
fedabipkgdiff --from fc23 foo-0.1-1.fc23.x86_64.rpm
fedabipkgdiff --from fc23 --to fc24 foo
fedabipkgdiff foo-0.1-1.fc23 foo-0.1-1.fc24
fedabipkgdiff foo-0.1-1.fc23.i686 foo-0.1-1.fc24.i686
fedabipkgdiff --all-subpackages foo-0.1-1.fc23 foo-0.1-1.fc24
* autoconf-archive/ax_compare_version.m4: New file copied from the
autoconf-archive project.
* autoconf-archive/ax_prog_python_version.m4: Likewise.
* autoconf-archive/ax_python_module.m4: Likewise.
* Makefile.am: Add the new files above to the source distribution.
* configure.ac: Include the new m4 macros from the autoconf
archive. Add a new --enable-fedabipkgdiff option. Update the
report at the end of the configure process to show the status of
the fedabipkgdiff feature. Add check for prerequisite python
modules argparse, glob, logging, os, re, shlex, subprocess, sys,
itertools, urlparse, itertools, shutil, unittest, xdg, koji and
mock. These are necessary for the unit test of
fedabipkgdiff. Generate tests/runtestfedabipkgdiff.py into the
build directory, from the tests/runtestfedabipkgdiff.py.in input
file.
* tools/Makefile.am: Include the fedabipkgdiff to the source
distribution and install it if the "fedabipkgdiff" feature is
enabled.
* tests/Makefile.am: Rename runtestfedabipkgdiff.sh into
runtestfedabipkgdiff.py. Add the new runtestfedabipkgdiff.py.in
autoconf template file in here.
* tests/runtestfedabipkgdiff.py.in: New unit test file.
* tools/fedabipkgdiff: New fedabipkgdiff tool.
* doc/manuals/fedabipkgdiff.rst: New manual.
Signed-off-by: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
abidiff, abipkgdiff and abicompat now recognize a [suppress_file]
directive in suppression specifications. That directive instructs the
tool to avoid loading some binaries altogether.
This is the first directive that won't act on the result of the
comparison of two binaries. It actually acts earlier and prevents the
tool from loading some binaries altogether.
The directive looks like:
[suppress_file]
# Don't load any library named lib_private*.so
file_name_regexp = lib_private.*\\.so
This prevents the tool from loading (and thus comparing) any library
which name matches the pattern "lib_private*.so".
[suppress_file]
# Only load libraries name lib_public*.so
file_name_not_regexp = lib_public.*\\.so
This instructs the tool to only load (and compare) files which name
match the pattern "lib_public*.so".
* doc/manuals/libabigail-concepts.rst: Document the new
'suppress_file' directive.
* include/abg-suppression.h (file_suppression): Define new class.
(file_suppression_sptr): Define new typedef.
(is_file_suppression, file_is_suppressed): Declare new functions.
* src/abg-suppression.cc ():
(read_file_suppression, is_file_suppression, file_is_suppressed):
Define new functions.
(file_suppression::{file_suppression, suppresses_file,
~file_suppression}): Define new member functions.
* tools/abidiff.cc (main): If a suppression specification
suppresses one of the input files, then do not perform the
comparison.
* tools/abipkgdiff.cc (compare): If a suppression specification
suppresses a file that is to be compared, then do not perform the
comparison.
* tools/abicompat.cc (create_diff_context): New static function.
(perform_compat_check_in_normal_mode)
(perform_compat_check_in_weak_mode): Adjust to take a context in
parameter. Do not create a diff context here anymore, do not load
suppression files here either.
(main): Use the new create_diff_context to create a diff context
and initialize it, including loading suppression specifications.
If any suppression specification suppresses a file to load, then
do not load perform any compatibility checking. Adjust
invocations of perform_compat_check_in_weak_mode and
perform_compat_check_in_normal_mode to pass the diff context.
* tests/data/test-diff-suppr/test0-type-suppr-3.suppr: New test
input.
* tests/data/test-diff-suppr/test0-type-suppr-4.suppr: Likewise.
* tests/data/test-diff-suppr/test0-type-suppr-report-4.txt: Likewise.
* tests/data/test-diff-suppr/test0-type-suppr-5.suppr: Likewise.
* tests/data/test-diff-suppr/test0-type-suppr-report-5.txt:
Likewise.
* tests/data/test-diff-suppr/test0-type-suppr-6.suppr: Likewise.
* tests/data/test-diff-suppr/test0-type-suppr-report-6.txt:
Likewise.
* tests/data/test-diff-suppr/test0-type-suppr-report-7.txt:
Likewise.
* tests/test-diff-suppr.cc (in_out_specs): Use the new test
inputs.
* tests/data/test-abicompat/test0-fn-changed-1.suppr: New test
input.
* tests/data/test-abicompat/test0-fn-changed-report-3.txt:
Likewise.
* tests/test-abicompat.cc (in_out_specs):: Use the new test
inputs.
* tests/data/Makefile.am: Add the new test material to source
distribution.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Until now, the suppression engine was part of the comparison engine.
The code of both was in the abg-comparison.{cc,h} files.
For the sake of greater modularity, this patch separates the suppression
engine from the comparison engine. The suppression engine now lives
in include/abg-suppression.h and src/abg-suppression.cc. The patch
also updates logical consumers of the suppression engine to adapt them
to the change.
* include/Makefile.am: Add abg-suppression.h to source
distribution.
* include/abg-comparison.h: Remove abg-ini.h include directive.
(suppression_sptr, suppressions_type): Move these typedefs to
abg-fwd.h.
(class suppression_base, type_suppression)
(type_suppression::insertion_range)
(type_suppression::insertion_range::boundary)
(type_suppression::insertion_range::integer_boundary)
(type_suppression::insertion_range::fn_call_expr_boundary)
(function_suppression, function_suppression::parameter_spec)
(variable_suppression): Move these type definitions to the new
abg-suppression.h.
(read_suppressions, is_type_suppression, is_integer_boundary)
(is_fn_call_expr_boundary, is_function_suppression)
(is_variable_suppression, operator&)
(operator|): Move these function declarations to the new
abg-suppression.h.
(type_suppression, type_suppression_sptr, type_suppression_type)
(function_suppression, function_suppression_sptr)
(function_suppressions_type, variable_suppression)
(variable_suppression_sptr, variable_suppressions_type): Move
these forward declaration and typedefs to the new
abg-suppression.h.
(diff_context::suppressions): Adjust return type to
suppr::suppressions_type&.
(diff_context::add_suppression): Adjust parameter type to
suppr::suppressions_sptr.
(diff_context::add_suppressions): Adjust parameter type
suppr::suppressions_type&.
(is_type_diff, is_decl_diff, is_var_diff, is_function_decl_diff)
(is_pointer_diff, is_reference_diff, is_fn_parm_diff)
(is_base_diff, is_child_node_of_function_parm_diff)
(is_child_node_of_base_diff): Declare these new functions. They
were previously static, local to abg-comparison.cc only. Now they
need to be exported because they are used by the suppression
engine's code that now lives in its one files.
* include/abg-fwd.h (suppr::{suppression_base, suppression_sptr,
suppressions_type}): Forward declare these here.
* include/abg-suppression.h (class suppression_base)
(type_suppression, type_suppression::insertion_range)
(type_suppression::insertion_range::boundary)
(type_suppression::insertion_range::integer_boundary)
(type_suppression::insertion_range::fn_call_expr_boundary)
(function_suppression, function_suppression::parameter_spec)
(variable_suppression): Move these type definitions here, in the
namespace suppr.
(read_suppressions, is_type_suppression, is_integer_boundary)
(is_fn_call_expr_boundary, is_function_suppression)
(is_variable_suppression, operator&)
(operator|): Move these function decalration here, in the
namespace suppr.
(type_suppression_sptr, type_suppressions_type)
(function_suppression_sptr, function_suppressions_type)
(variable_suppression_sptr, variable_suppressions_type): Move
these typedefs here, in the namespace suppr.
* src/Makefile.am: add src/abg-suppression.cc to source
distribution.
* src/abg-comparison.cc (is_type_diff, is_decl_diff, is_var_diff)
(is_function_decl_diff, is_pointer_diff, is_reference_diff)
(is_reference_or_pointer_diff, is_fn_parm_diff, is_base_diff)
(is_child_node_of_function_parm_diff, is_child_node_of_base_diff):
Export these functions.
(*suppression*): Move all the suppression-related definitions to
the new abg-suppression.cc.
* src/abg-suppression.cc: New file. Contains all the *suppression*
definitions from src/abg-comparison.cc, that are put in the suppr
namespace.
* tools/abicompat.cc: Adjust.
* tools/abidiff.cc: Likewise.
* tools/abipkgdiff.cc: Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch adds the following convenience command line options
shortcuts:
--suppr, --appd, --libd1, --libd2
for the following command line options:
--suppressions, --app-debug-info-dir, --lib-debug-info-dir1,
--lib-debug-info-dir2
The patch also updates the documentation accordingly.
* doc/manuals/abicompat.rst: Update documentation.
* tools/abicompat.cc (display_usage): Update help strings.
(parse_command_line): Add shortcuts --suppr, --appd, --libd1 and
--libd2.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When a suppression specification file was not found, from the command line
of abidiff, the error message fails to mention the name of the tool.
This patch fixes that.
* src/abg-tools-utils.cc (emit_prefix): Try to emit the prefix
only if the program name was provided.
* abidiff.cc (maybe_check_suppression_files): Pass the name of the
tool to the check_file function.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* doc/manuals/libabigail-concepts.rst: Do not refer to abidiff
specifically for suppressions because several tools use
suppressions.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-dwarf-reader.h (namespace dwarf_reader): Add apidoc.
(enum elf_type): Add an apidoc for each enumerator.
* src/abg-dwarf-reader.cc (get_type_of_elf_file): Add an apidoc
for the 'type' parameter.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When abipkgdiff says that a library was added or removed, it doesn't
tell us about the SONAME of that library, making it hard for the user
to guess that maybe this adding/removal is probably due to a SONAME
change.
This patch fixes that.
* tools/abipkgdiff.cc (abi_diff::{added,removed}_binaries): Change
the type of these data member from vector<string> to
vector<elf_file_sptr>.
(compare): Adjust. Show the soname of added/removed binaries.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The supression directives suppress_type, suppress_function and
suppress_variable support the two properties below, among others:
file_name_regexp = <some-regexp>
soname_regexp = <some-regexp>
When the regular expression matches either the file name or the
soname, then the suppression directive is activated.
This patch adds the support for these two additional properties for
these suppression directives:
file_name_not_regexp = <some-regexp>
soname_not_regexp = <some-regexp>
These activate the current suppression directive if the regular
expression does *NOT* match the file name or soname.
This is very helpful to express change report suppressions like:
"suppress all ABI change reports for all libraries but those with
file names (or sonames) with the pattern libfoobar.*"
* include/abg-comparison.h
(suppression_base::{get,set}_file_name_not_regex_str): Declare new
member functions.
(suppression_base::{get,set}_soname_not_regex_str): Likewise.
(suppression_base::{names,sonames}_of_binaries_match): Likewise.
* src/abg-comparison.cc
(suppression_base::priv::get_file_name_regex): Fix comment.
(suppression_base::priv::get_file_name_not_regex): New member
function.
(suppression_base::priv::get_soname_regex): Fix comment.
(suppression_base::priv::get_soname_not_regex): New member
function.
(suppression_base::{get,set}_file_name_not_regex_str): Define new
member functions.
(suppression_base::{get,set}_soname_not_regex_str): Likewise.
(suppression_base::{names,sonames}_of_binaries_match): Likewise.
These got factorized out of type_suppression::suppresses_type,
function_suppression::suppresses_function,
function_suppression::suppresses_function_symbol,
variable_suppression::suppresses_variable,
variable_suppression::suppresses_variable_symbol.
(type_suppression::suppresses_type): Use the new
suppression_base::{names,sonames}_of_binaries_match.
(read_type_suppression): Read the new file_name_not_regexp and
soname_not_regexp properties.
(function_suppression::{suppresses_function,
suppresses_function_symbol}): Use the new
suppression_base::{names,sonames}_of_binaries_match.
(read_function_suppression): Read the new file_name_not_regexp and
soname_not_regexp properties.
(variable_suppression::{suppresses_variable,
variable_suppression::suppresses_variable_symbol}): Use the new
suppression_base::{names,sonames}_of_binaries_match.
(read_variable_suppression): Use the new
suppression_base::{names,sonames}_of_binaries_match.
* doc/manuals/libabigail-concepts.rst: Document the new
file_name_not_regexp and soname_not_regexp suppression properties.
* tests/data/test-diff-suppr/test24-soname-report-10.txt: New test
reference output.
* tests/data/test-diff-suppr/test24-soname-report-11.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-report-12.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-report-13.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-report-14.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-report-15.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-report-16.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-report-9.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-suppr-10.txt: New test input.
* tests/data/test-diff-suppr/test24-soname-suppr-11.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-suppr-12.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-suppr-13.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-suppr-14.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-suppr-15.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-suppr-16.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-suppr-9.txt: Likewise.
* tests/data/test-diff-suppr/test29-soname-report-2.txt: New test
reference output.
* tests/data/test-diff-suppr/test29-soname-report-3.txt: Likewise.
* tests/data/test-diff-suppr/test29-soname-report-4.txt: Likewise.
* tests/data/test-diff-suppr/test29-soname-report-5.txt: Likewise.
* tests/data/test-diff-suppr/test29-soname-report-6.txt: Likewise.
* tests/data/test-diff-suppr/test29-soname-report-7.txt: Likewise.
* tests/data/test-diff-suppr/test29-soname-report-8.txt: Likewise.
* tests/data/test-diff-suppr/test29-suppr-2.txt: New test input.
* tests/data/test-diff-suppr/test29-suppr-3.txt: Likewise.
* tests/data/test-diff-suppr/test29-suppr-4.txt: Likewise.
* tests/data/test-diff-suppr/test29-suppr-5.txt: Likewise.
* tests/data/test-diff-suppr/test29-suppr-6.txt: Likewise.
* tests/data/test-diff-suppr/test29-suppr-7.txt: Likewise.
* tests/data/test-diff-suppr/test29-suppr-8.txt: Likewise.
* tests/data/Makefile.am: Add the new test material to source
distribution.
* tests/test-diff-suppr.cc (in_out_specs): Make this test harness
run over the new test inputs.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-workers.h: Document the workers namespace, the task,
queue and queue::task_done_notify types.
* src/abg-workers.cc: Move the documentation of the thread_pool
module inside the abigail::worker namespace, so that references to
task and queue types (which are also in the abigail::worker
namespace) can be resolved in the apidoc.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* COMPILING: Add python-sphinx to the set of required packages to
build the documentation.
* doc/website/mainpage.txt: Update the website to mention doxygen
and python-sphinx for documentation.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* Makefile.am: Add info, man and html-doc targets to generate
documentation in info, man and html formats. If you want to
generate them all, then the doc target is the one to be used.
* COMPILING: Add documentation for the above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Registering alias of functions on ppc64 seems to be broken since this
commit:
11f5dba Bug 19885 - Cannot associates a function DIE to a symbol on powerpc64
This is because the ppc64-specific code tries to register a symbol
alias that was already registered as an alias by the arch-agnostic
code.
This patch fixes that.
* src/abg-dwarf-reader.cc (read_context::load_symbol_maps): While
filling the ppc64-specific "function-entry-address => symbol" map,
if we stumble accross a function-entry-address that belongs to an
alias of 'symbol', then assume the alias must have been registered
as an alias already, by the platform-agnostic code. Do not try to
register the alias again.
* tests/data/Makefile.am: Add the new test input binaries to the
source distribution.
* tests/data/test-diff-dwarf/libtest36-ppc64-aliases-v0.so: New
binary test input.
* tests/data/test-diff-dwarf/libtest36-ppc64-aliases-v1.so: Likewise.
* tests/data/test-diff-dwarf/test36-ppc64-aliases-report-0.txt:
New test reference output.
* tests/data/test-diff-dwarf/test36-ppc64-aliases-v0.cc: Source
code for the new binary test input above.
* tests/data/test-diff-dwarf/test36-ppc64-aliases-v1.cc: Likewise.
* tests/test-diff-dwarf.cc: Add the new test input to the list of
test inputs considered by this test harness.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
In the ELF format, Position Independent Executables (aka PIE) and
shared libraries are marked as being of type ET_DYN. So just looking
at the type of the ELF file is not enough to discriminate a position
independent executable from a shared library.
And this is the problem. Libabigail just looks at the type of the ELF
file to discriminate PIE binaries from shared libraries binaries.
So it treats both kinds of binaries as being shared libraries. When
we run abipkgdiff with the --dso-only option, the tool considers both
PIEs and shared libraries, even though the intent of the --dso-only
option is have the tool consider shared libraries only.
With this patch, we introduce a new enumerator ELF_TYPE_PI_EXEC (to
the elf_type enum) for PIE binaries. From now on, a file will be
properly recognized as being of the ELF_TYPE_DSO kind only if it is a
shared library.
* include/abg-dwarf-reader.h (elf_type): Add new enumerator
ELF_TYPE_PI_EXEC.
* src/abg-dwarf-reader.cc
(lookup_data_tag_from_dynamic_segment): New function for
data tag lookup in dynamic segment of an elf
(elf_file_type): Return ELF_TYPE_PI_EXEC file type for
a PI executable.
(get_elf_file_type): Change this to take an elf handle.
(get_type_of_elf_file): New function that got factorized out of ...
(load_dt_soname_and_needed): ... this one.
* tools/abipkgdiff.cc (create_maps_of_package_content): Also
consider ELF_TYPE_PI_EXEC file type.
(compare): Likewise.
* tests/test-diff-pkg.cc (in_out_specs): Test case additions
* tests/data/Makefile.am: Include test files
* tests/data/test-diff-pkg/tarpkg-1-dir1.tar.gz: New test data
* tests/data/test-diff-pkg/tarpkg-1-dir2.tar.gz: New test data
* tests/data/test-diff-pkg/tarpkg-1-report-0.txt: New test result
Signed-off-by: Sinny Kumari <sinny@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Add a release target that tags and uploads the release.
* Makefile.am: Add tarball, upload-release-only, upload-release
and release targets.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
In a suppression specification, soname_regexp or file_name_regexp
cannot be the only property of a suppression directive. For instance,
the suppression specification below won't work:
[suppress_type]
# suppress all change reports about *any type* from the library
# libtestfoo.so
file_name_regexp = libtestfoo.so
This is because as documented in the manual, the suppression directive
'suppress_type' requires that some other properties be specified. For
instance, the below would work:
[suppress_type]
name_regexp = .*
file_name_regexp
This was done on purpose to prevent folks from inadvertently
suppressing too much of change report bits.
But experience is showing that this is surprising some users. And in
hindsight, I kind of agree it's surprising.
So this patch allows the first example to work, as seems to be
expected.
The patch allows the first example to work for the suppress_function
and suppress_variable directive too.
* doc/manuals/libabigail-concepts.rst: Update the manual to
reflect the changes in the suppression_type, suppress_function and
suppress_variable directives.
* src/abg-comparison.cc (read_type_suppression): Accept that
the suppress_type directive contains only file_name_regexp
or the soname_regexp property.
(read_function_suppression): Likewise for the suppress_function
directive.
(read_variable_suppression): Likewise for the suppress_variable
directive.
* tests/data/test-diff-suppr/libtest29-soname-v0.so: New binary
test input.
* tests/data/test-diff-suppr/libtest29-soname-v1.so: Likewise.
* tests/data/test-diff-suppr/test24-soname-report-5.txt: New
reference test output.
* tests/data/test-diff-suppr/test24-soname-report-6.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-report-7.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-report-8.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-suppr-5.txt: New test
suppression file.
* tests/data/test-diff-suppr/test24-soname-suppr-6.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-suppr-7.txt: Likewise.
* tests/data/test-diff-suppr/test24-soname-suppr-8.txt: Likewise.
* tests/data/test-diff-suppr/test29-soname-report-0.txt: New
reference test output.
* tests/data/test-diff-suppr/test29-soname-report-1.txt: Likewise.
* tests/data/test-diff-suppr/test29-soname-v0.cc: Source code for
the new binary output above.
* tests/data/test-diff-suppr/test29-soname-v1.cc: Likewise.
* tests/data/test-diff-suppr/test29-suppr-0.txt: New test
suppression file.
* tests/data/test-diff-suppr/test29-suppr-1.txt: Likewise.
* tests/data/Makefile.am: Add the new test material above to
source distribution.
* tests/test-diff-suppr.cc (in_out_specs): Make this test harness
run over the new test input above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
On powerpc 64 ELFv1, the address of a function is different from the
address of the entry point of that function. The value of a en ELF
symbol represents the address of the function, whereas the
DW_AT_low_pc DWARF attribute of a function DIE points to the entry
point address of the function. So to get the symbol a function's
DW_AT_low_pc points to, one needs to get the address of the function
*from* the address of its entry point.
More precisely, on ppc64, the address of a function is the address of
a function descriptor. The function descriptor is a set of three 64
bits addresses. The first element of the triplet is the function
entry pointer address. So to get the symbol a given function entry
point address belongs to, one must get to the function descriptor
which contains said function entry point address. And function
descriptors are in the ".opd" special section.
Unfortunately, Libabigail's ELF/DWARF reader has no knowledge of all
this. So it cannot get the symbol of a given function DWARF
description. So it considers all functions as having no ELF symbols.
So it shows no ABI change pertaining to function sub-types on ppc64.
This patch makes Libabigail support function descriptors on ppc64 so
it can detect changes on function sub-types there.
* src/abg-dwarf-reader.cc (read_context::{opd_section_,
fun_entry_addr_sym_map_}): New data members.
(read_context::read_context): Initialize the new opd_section_ data
member.
(read_context::{find_opd_section,
lookup_ppc64_elf_fn_entry_pointer_address,
fun_entry_addr_sym_map_sptr, fun_entry_addr_sym_map,
elf_architecture_is_ppc64, elf_architecture_is_big_endian}): New
member functions.
(read_context::lookup_elf_fn_symbol_from_address): Adjust to use
the new read_context::fun_entry_addr_sym_map() function.
(read_context::load_symbol_maps): Populate the function entry
addresses -> symbol map, for ppc64 ELFv1.
(read_context::load_elf_properties): Renamed
read_context::load_remaining_elf_data into this.
(read_corpus_from_elf): Load elf properties before trying to load
elf symbols information.
* tests/data/test-diff-filter/libtest32-struct-change-v0.so: New
binary test input, compiled for ppc64le.
* tests/data/test-diff-filter/libtest32-struct-change-v1.so: Likewise.
* tests/data/test-diff-filter/test32-ppc64le-struct-change-report0.txt:
New test reference output.
* tests/data/test-diff-filter/test32-ppc64le-struct-change-v0.c:
Source code of the new binary test input above.
* tests/data/test-diff-filter/test32-ppc64le-struct-change-v1.c:
Likewise.
* tests/data/Makefile.am: Add the new test material above to
source distribution.
* tests/test-diff-filter.cc (in_out_spec): Make this test harness
run over the new test input binaries above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* tools/abipkgdiff.cc (compare): Fix logs to make them more
readable in a multithreaded context.
(create_maps_of_package_content): Likewise. Add logs about the
number of elf files found in a given directory. Add logs about
skipping files.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When comparing two directories, abipkgdiff skips symbolic links
pointing to ELF binaries altogether. It only consider regular files.
This is a problem when abipkgdiff is given two directories that only
contain symbolic links. In that case, abipkgdiff just performs no
comparison.
This patch makes abipkgdiff resolve the symbolic link to its target
file.
* include/abg-tools-utils.h (maybe_get_symlink_target_file_path):
Declare new function.
* src/abg-tools-utils.cc (get_stat): Use lstat here, not stat.
Update comment.
* tools/abipkgdiff.cc (first_package_tree_walker_callback_fn)
(second_package_tree_walker_callback_fn): Follow symbolic links to
elf files to get their target paths, and only work with that
target path.
(maybe_get_symlink_target_file_path): Define new function.
* test-diff-pkg/symlink-dir-test1-report0.txt New test material.
* test-diff-pkg/symlink-dir-test1/dir1/symlinks/foo.o: Likewise.
* test-diff-pkg/symlink-dir-test1/dir1/symlinks/libfoo.so: Likewise.
* test-diff-pkg/symlink-dir-test1/dir1/targets/foo.c: Likewise.
* test-diff-pkg/symlink-dir-test1/dir1/targets/foo.o: Likewise.
* test-diff-pkg/symlink-dir-test1/dir1/targets/libfoo.so: Likewise.
* test-diff-pkg/symlink-dir-test1/dir2/symlinks/foo.o: Likewise.
* test-diff-pkg/symlink-dir-test1/dir2/symlinks/libfoo.so: Likewise.
* test-diff-pkg/symlink-dir-test1/dir2/targets/foo.c: Likewise.
* test-diff-pkg/symlink-dir-test1/dir2/targets/foo.o: Likewise.
* test-diff-pkg/symlink-dir-test1/dir2/targets/libfoo.so: Likewise.
* tests/data/Makefile.am: Add the new test material to source
distribution.
* tests/test-diff-pkg.cc (in_out_spec): Run this test harness
over the new test material above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>