Dodji Seketeli [Sat, 22 Aug 2015 09:44:08 +0000 (11:44 +0200)]
Make abipkgdiff compare directories containing binaries
abipkgdiff knows how to compare the ABI of binaries contained in .deb
and .rpm files. This patch adds support for comparing the ABI of
binaries contained in two directories.
* include/abg-tools-utils.h (enum file_type): Add a new
FILE_TYPE_DIR enumerator.
* src/abg-tools-utils.cc (operator<<(ostream&, file_type)):
Support serialization of the new FILE_TYPE_DIR enumerator.
(guess_file_type): Detect that the path given is a directory.
* tools/abipkgdiff.cc (package::package): If the package is a
directory, then set its extracted directory path to the path of
the directory.
(package::erase_extraction_directory): Do not erase the extraction
directory if the package is a directory provided by the user.
(extract_package): If the package is a directory provided by the
user, then there is nothing to extract.
(main): If the first package is a directory, then the second one
should be a directory as well.
* tools/abidiff.cc (main): Support directories as input.
* tools/abilint.cc (main): Likewise.
* tests/data/test-diff-pkg/dirpkg-0-dir{1,2}/libobj-v0.so: New
binary test inputs.
* test/data/test-diff-pkg/dirpkg-0-report-0.txt: New input test
file.
* tests/data/test-diff-pkg/dirpkg-1-dir{1,2}/obj-v0.cc: Source
code of the binary test inputs above.
* tests/data/Makefile.am: Add the new files above to the source
distribution.
* tests/test-diff-pkg.cc (in_out_specs): Add the new test input
files above to the set of tests this harness has to run over.
Dodji Seketeli [Sat, 22 Aug 2015 07:33:13 +0000 (09:33 +0200)]
[dwarf reader] Support reference types without explicit DW_AT_byte_size
On x86_64 at least, in the debug info emitted by Clang, reference
types don't necessarily have the DW_AT_byte_size property. In that
case, assume the size of the pointer type is the address size of the
current translation unit, rather than giving up and not building the
type.
* src/abg-dwarf-reader.cc (build_reference_type): If the type DIE
has no DW_AT_byte_size, assume the type size is the translation
unit's address size.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
Dodji Seketeli [Fri, 21 Aug 2015 18:16:38 +0000 (20:16 +0200)]
[dwarf reader] Support pointer types without explicit DW_AT_byte_size
On x86_64 at least, in the debug info emitted by Clang, pointer types
don't necessarily have the DW_AT_byte_size property. In that case,
assume the size of the pointer type is the address size of the
current translation unit, rather than giving up and not building the
type.
* abg-dwarf-reader.cc (build_pointer_type_def): If the type DIE
has no DW_AT_byte_size, assume the type size is the translation
unit's address size.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
Dodji Seketeli [Fri, 21 Aug 2015 11:08:38 +0000 (13:08 +0200)]
make abipkgdiff compile with GCC 4.4.7
GCC 4.4.7 won't let us declare an instance of string with __thread.
So for now, package::extracted_packages_parent_dir() juststores its string
globally. We are single-threaded for now anyway.
* tools/abipkgdiff.cc (package::extracted_packages_parent_dir):
The string holding the dir name is no more __thread, as this won't
compile with GCC 4.4.7
Dodji Seketeli [Fri, 21 Aug 2015 10:15:21 +0000 (12:15 +0200)]
Misc style fixes
* src/abg-dwarf-reader.cc (read_context::die_type_map): Fix typo
in the comment.
* src/abg-ir.cc (peel_typedef_type): Fix typo in the comment.
* src/abg-reader.cc
(read_context::perform_late_type_canonicalizing): Fix a type in
the comment.
Dodji Seketeli [Fri, 21 Aug 2015 10:09:22 +0000 (12:09 +0200)]
Make get_pretty_representation work on method types
Until now, get_pretty_representation() considered method types just as
function types. This patch makes it know about them specifically. This
useful for debugging, at least.
* include/abg-fwd.h (is_method_type): Declare new overloads for
naked pointers.
(get_method_type_name): Declare new functions.
(get_pretty_representation): Declare new overloads for
method_type.
* src/abg-ir.cc (get_function_type_name): If the function type is
a method type, handle it as such.
(get_method_type_name): Define new functions.
(get_pretty_representation): If the function type is a method
type, handle it as such.
(get_pretty_representation): Define new overloads for method_type
and pointer/reference to method_type.
(is_method_type): Add overloads for naked pointers.
Dodji Seketeli [Fri, 21 Aug 2015 09:22:30 +0000 (11:22 +0200)]
Hash a class declaration the same as its definition
A class declaration hashes differently from its definition.
Since the abixml format can now use a class element id before defining
it, it's more consistent to stop representing class declarations in
the abixml format, when the class is actually defined in the corpus.
So this patch now hashes a class declaration the same as its
definition, when the definition is present. If the definition is not
present then the hash value of the declaration is just zero. This is
consistent with what is done elsewhere in the code as a hash value of
zero means the hash could not be computed, somehow, as the type
comparison code knows that a type with hash value zero can be equal to
a type with a hash value that is different from zero.
As a result, many tests which use the abixml format have been adjusted
to reflect the new form of abixml where class declarations are now
omitted when these declarations are accompanied with their definition.
I made sure that abidiff reports that former abixml output and the new
one are equivalent.
After this change abixml outputs should contain less redundant type
declarations. This is another step toward normalizing the abixml
output.
* src/abg-hash.cc (class_decl::hash::operator()(const class_decl&)):
If the class declaration has a definition, hash its definition
instead. Otherwise, if the class declaration has no definition,
just return a zero hash, like what we were doing before.
* src/abg-reader.cc (read_context::maybe_canonicalize_type): Do
not early canonicalize method types because most of the time, when
this function is called, the method hasn't been added to its
parent class yet. So wait until late before canonicalizing.
* src/abg-writer.cc (write_class_is_declaration_only): Do not emit
the "is-declaration-only" property if the declaration has a
definition.
(write_class_decl): If the class declaration has a definition,
emit the definition instead.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
* tests/data/test-read-write/test18.xml: Likewise.
* tests/data/test-read-write/test20.xml: Likewise.
* tests/data/test-read-write/test21.xml: Likewise.
Dodji Seketeli [Thu, 20 Aug 2015 10:28:38 +0000 (12:28 +0200)]
Add a --stats to abidiff and abidw
For now, this new --stats emits diagnostics about the number of types
canonicalized at the very end of building the ABI corpus as well as
the number of types that were scheduled for late canonicalizing and
that couldn't be canonicalized.
* include/abg-dwarf-reader.h (get_show_stats)
(set_show_stats): New accessors for a new "show_stats" property of
the dwarf reader context.
* src/abg-dwarf-reader.cc: Include iostream to use std::cerr.
(dwarf_reader::show_stats_): New data member.
(dwarf_reader::dwarf_reader): Initialize it.
(dwarf_reader::show_stats)
(get_show_stats)
(set_show_stats): Define new accessors.
(dwarf_reader::die_type_map): Add const overload to this accessor.
(dwarf_reader::lookup_type_from_die_offset): Make this accessor
const.
(dwarf_reader::add_late_canonicalized_types_stats): New member
function.
(dwarf_reader::perform_late_type_canonicalizing): Emit the
statistics about late-canonicalized types if the user asked for
it.
* tools/abidiff.cc (options::show_stats): New data member.
(options::options): Initialize it.
(display_usage): Document it.
(parse_command_line): Parse the new --stats option.
(main): Create a dwarf reader context, set the show_stats to it
and then use that context to read the corpora before diffing them.
* tools/abidw.cc (options::show_stats): New data member.
(options::options): Initialize it.
(display_usage): Document it.
(parse_command_line): Parse the new --stats option.
(main): Set the show_stats to the dwarf reader context before
using it.
* doc/manuals/abidiff.rst: Update the manual.
* doc/manuals/abidw.rst: Update the manual.
Dodji Seketeli [Wed, 19 Aug 2015 16:59:53 +0000 (18:59 +0200)]
Canonicalize all types that got scheduled for late canonicalization
Until now, when late type canonicalization time come (after having
read all of the ABI corpus), the types scheduled for late
canonicalization were considered and only those that don't have
non-canonicalized sub-types were canonicalized.
This patch just canonicalizes all the scheduled type. As a result,
all types should now be canonicalized, so type comparison should be as
fast as a pointer comparison now. But then, loading DWARF is now even
longer, type canonicalization needs to happen.
* src/abg-dwarf-reader.cc
(read_context::canonicalize_types_scheduled): Canonicalize all
types scheduled for late canonicalization.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
Dodji Seketeli [Wed, 19 Aug 2015 16:21:38 +0000 (18:21 +0200)]
Propagate canonical type of a class definition to its declaration
When a class type definition has its canonical type set, propagate it
to the class declaration.
* src/abg-ir.cc: (canonicalize): Propagate the canonical type of
the type definition to its declaration.
(class_decl::set_definition_of_declaration): Likewise.
Dodji Seketeli [Wed, 19 Aug 2015 14:15:28 +0000 (16:15 +0200)]
Make type_has_non_canonicalized_subtype() tighter
type_has_non_canonicalized_subtype() gives up too quickly.
For instance, suppose it's looking a type 'foo'. If foo has no
canonicalized type yet and has a data member which type is foo* (for
instance), then type_has_non_canonicalized_subtype() just sees that
type 'foo*' has no canonicalized type, and so it returns, saying that
he found a non-canonicalized subtype for foo.
In that case though, what type_has_non_canonicalized_subtype() should
do is detect that foo* is a pointer to foo itself, so it shouldn't
count as a non-canonicalized sub-type. It should keep going and look
for other meaningful non-canonicalized sub-types.
And this what this patch does. It changes the sub-type walker that
type_has_non_canonicalized_subtype() uses, so that
- it doesn't flag sub-types that refer to the type we are looking
at as non-canonicalized sub-types. This is for sub-types that
are combinations of pointers, references and typedefs.
- it doesn't consider sub-types of member functions of the type we
are looking at, unless that member function is virtual.
The result is that more types are canonicalized early during DWARF
reading, and so there are less types to store on the side for late
canonicalization. This can have a big impact on, e.g, C++ libraries
with tens of thousands of types.
* include/abg-fwd.h (is_typedef, is_pointer_type)
(is_reference_type): Declare new overloads.
(peel_typedef_type): Renamed get_typedef_underlying_type into
this.
(peel_pointer_type, peel_reference_type)
(peel_typedef_pointer_or_reference_type): Declare new functions.
* src/abg-ir.cc (peel_typedef_type): Renamed
get_typedef_underlying_type into this.
(is_typedef, is_pointer_type, is_reference_type): Define new
overloads.
(peel_pointer_type, peel_reference_type)
(peel_typedef_pointer_or_reference_type): Define new functions.
(non_canonicalized_subtype_detector::has_non_canonical_type_):
Make the type of this data member be a type_base*, not a bool.
This is so that we can return the first non-canonicalized subtype
of the type we are looking at.
(non_canonicalized_subtype_detector::non_canonicalized_subtype_detector):
Adjust the data member initialization.
(non_canonicalized_subtype_detector::visit_begin): Add an overload
for function_decl*, to avoid looking into non-virtual member
functions.
In the overload for type_base*, peel typedefs, pointers and
reference of each sub-type that has no canonical type, to see if
refers to the type we are actually walking. If yes, then keep
going.
(type_has_non_canonicalized_subtype): Return the non-canonicalized
sub-type found.
* src/abg-comparison.cc (type_suppression::suppresses_diff):
Adjust for the get_typedef_underlying_type -> peel_typedef_type
renaming.
Dodji Seketeli [Wed, 19 Aug 2015 10:06:24 +0000 (12:06 +0200)]
Make decl_base::get_qualified_name() work when decl context changes
decl_base::get_qualified_name() caches its result. So when it's
first called on a decl that is not added to a scope, what is returned
is a non-qualified name. Which is all right. But then when the decl
is later added to a scope, the cached result of
decl_base::get_qualified_name() is not longer correct.
This patch resets the cache of decl_base::get_qualified_name() when
the decl gets added to a new scope.
* include/abg-ir.h (class decl_base): Make class scope_decl a
friend of decl_base.
(type_base::priv_): Make this protected, rather than private.
* src/abg-ir.cc (scope_decl::add_member_decl)
(scope_decl::insert_member_decl): Reset the cache of the result of
decl_base::get_qualified_name().
* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
Dodji Seketeli [Tue, 18 Aug 2015 10:33:57 +0000 (12:33 +0200)]
Bug 18844 - assert failure in abidw at abg-dwarf-reader.cc:6537
The DWARF reader is not scheduling a declaration-only class for
resolution when the class has member types. When reading the code of
build_class_type_and_add_to_ir(), we see that the scheduling is done
before getting out of the function. But then, building members of the
class can trigger another invocation of
build_class_type_and_add_to_ir() before the current invocation
returns. In that case, the declaration-only class being built appears
as not being scheduled for resolution. And that is what violates the
assertion that declaration-only classes should be scheduled for
resolution whenever they are used.
This patch addresses the issue by scheduling the resolution earlier, when
we know we are dealing with a declaration-only class, and before
dealing with members of that classes.
* src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir):
Schedule declaration-only class resolution before the class
appears as usable as to other types being built.
* tests/data/test-read-dwarf/test12-pr18844.so: Add a new binary
test input.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: The reference
ABI XML output for the binary above.
* tests/data/Makefile.am: Add the new test inputs above to the
source distribution.
* tests/test-read-dwarf.cc (in_out_specs): Add the new test inputs
above to the set of input this test harness has to run over.
Dodji Seketeli [Tue, 18 Aug 2015 10:31:45 +0000 (12:31 +0200)]
Fix a little glitch in the test suite
* test-read-dwarf.cc (in_out_specs): Emit the output of the test11
to output/test-read-dwarf/test11-pr18828.so.abi, not
output/test-read-dwarf/test10-pr18828.so.abi.
Dodji Seketeli [Tue, 18 Aug 2015 10:07:18 +0000 (12:07 +0200)]
Escape XML property names that were not escaped before
Apparently we are not escaping XML property names for 'typedef-decl',
'namespace-decl' and 'var-decl' elements. I think it's not necessary
for namespace-decl, but well, you never know.
* src/abg-writer.cc (write_namespace_decl, write_typedef_decl)
(write_var_decl): Escape the XML characters that are forbidden in
XML properties, and that are emitted as value of the 'name'
property.
Dodji Seketeli [Fri, 14 Aug 2015 22:10:26 +0000 (00:10 +0200)]
Bug 18828 - Handle force-resolving of multiple declarations-only of the same type
When a declaration-only type that is used in a context where it needs
to be complete (and no definition is present for that type in the ABI
corpus) handle cases where that type is was actually declared several
times.
* src/abg-dwarf-reader.cc
(read_context::resolve_declaration_only_classes): Accept that a
class that needs to be force-resolved might have been declared
several times. In that case, some instances of that
declaration-only class might have already been resolved (or
completed).
* tests/data/test-read-dwarf/test11-pr18828.so: New binary input.
It comes from bug https://sourceware.org/bugzilla/show_bug.cgi?id=18828.
* tests/data/test-read-dwarf/test11-pr18828.so.abi: The reference
output for the binary above.
* tests/data/Makefile.am: Add the test input files above to source
distribution.
* tests/test-read-dwarf.cc (in_out_specs): Add the test inputs
above to the set of input this test harness has to run over.
Dodji Seketeli [Fri, 14 Aug 2015 22:03:07 +0000 (00:03 +0200)]
Avoid declaring a type several times in the same TU in the XML format
It appears a lot of duplicated type declarations can appear in a given
translation unit. This patch avoids that.
* src/abg-writer.cc (write_context::{record_type_id_as_emitted,
record_type_as_emitted, type_id_is_emitted, type_is_emitted,
clear_emitted_types_map}): New member functions.
(write_context::m_emitted_type_id_map): New data member.
(write_translation_unit): Clear the per-translation unit map of
emitted types. Do not emit a type that has already been emitted
in this translation unit.
(write_namespace_decl): Do not emit a type that has already been
emitted in this translation unit.
(write_type_decl, write_qualified_type_def)
(write_pointer_type_def, write_reference_type_def)
(write_array_type_def, write_typedef_decl, write_class_decl)
(write_type_tparameter, write_template_tparameter): Record the
type we've just written as having been written out.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust as
duplicated declarations got removed.
Dodji Seketeli [Fri, 14 Aug 2015 21:45:14 +0000 (23:45 +0200)]
Misc style fixes in the XMLABI writer
This patch aligns some data members and function parameters. It also
makes use of the *_sptr typedef, rather than the longer
shared_ptr<something> types in function parameters.
* src/abg-writer.cc (write_context): Align data members.
(write_translation_unit): Remove useless horizontal white spaces.
(write_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_class_decl)
(write_type_tparameter): Use the *_sptr typedefs rather than the
longer form of shared_ptr<sometype> in function signatures.
(write_enum_type_decl): In this function in particular, indent a
line properly.
Dodji Seketeli [Fri, 14 Aug 2015 14:50:18 +0000 (16:50 +0200)]
Fix typos in abipkgdiff
* tools/abipkgdiff.cc (display_usage): s/pompare/compare. Give a
better help message for --help.
(extract_rpm): Insert a space after the path of the package being
extracted, when emitting a verbose message.
Dodji Seketeli [Wed, 12 Aug 2015 21:55:18 +0000 (23:55 +0200)]
Bug 18818 - abidw aborts on a class with a non-complete base class
On some binaries with debug info emitted by "Ubuntu clang version
3.6.0-2ubuntu1" and "GNU C++ 4.9.2" (as the value of the
DW_AT_producer property), it seems some classes can have a base class
that is not complete. E.g, the debug info (that I have extracted
using the command eu-readelf --debug-dump=info
<the-binary-attached-to-the-bug>) has these relevant pieces:
Here, we are looking at the type system_error (actually
boost::system::system_error) that inherits the type which DIE is
referred to as offset '7480'.
Then the definition of the DIE at offset 7480 is:
[...]
[ 7480] class_type
name (strp) "runtime_error"
declaration (flag_present)
[ 7485] class_type
name (strp) "exception"
declaration (flag_present)
[...]
You can see that the type "runtime_error" (actually
std::runtime_error) has the flag DW_AT_declaration set, marking it as
a declaration (with no definition yet). And no other DIE in the same
translation unit
(src/third_party/boost-1.56.0/libs/filesystem/src/codecvt_error_category.cpp)
or in the same DSO provides the definition for that declaration.
I believe this is ill-formed. A base class should be defined and have
a layout completed expressed and accessible from the translation unit
it's used in.
The patch I am proposing detects that the base class is still
incomplete when we finish loading the current binary. In that case,
the base class is made complete with a size of 1. Meaning it's an
empty class (with no data member and no base class). This works as a
viable work-around *if* the producer only omitted definitions for
empty classes. We'll need to fix the producers eventually.
* src/abg-dwarf-reader.cc
(read_context::decl_only_classes_to_force_defined_map_): New data
member.
(read_context::declaration_only_classes_to_force_defined): New
accessors.
(read_context::schedule_declaration_only_class_for_forced_resolution):
New member function.
(build_class_type_and_add_to_ir): If a base class is a
declaration-only class then mark it as needing to be force-defined
*if* it's still not defined at the end of the abi corpus loading.
(read_context::resolve_declaration_only_classes): If
declaration-only classes that need to force-defined are present
and not defined (when we reach the end of the ABI corpus) then
force-define them as empty classes.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so: New test
binary input file. This comes from a user binary submitted to bug
https://sourceware.org/bugzilla/show_bug.cgi?id=18818. The
original URL to the binary is
https://sourceware.org/bugzilla/attachment.cgi?id=8518.
* tests/data/test-read-dwarf/test9-pr18818-clang.so: New binary
input file. This comes from the same bug report as above. The
original URL to the binary is
https://sourceware.org/bugzilla/attachment.cgi?id=8511.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: New
reference output file.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
* tests/data/Makefile.am: Add the new files above to the source
distribution.
* tests/test-read-dwarf.cc (in_out_specs): Add the test inputs
above the set of tests input this harness has to run over.
Dodji Seketeli [Fri, 14 Aug 2015 10:49:57 +0000 (12:49 +0200)]
Make the support of RPM and DEB package formats conditional
If at configure time the libabigail source tarball detects that
rpm2cpio and cpio are present then it enables the support for rpm
files. Users can explicitly enable or disable that support by passing
--enable-rpm or --disable-rpm to configure.
Similarly if it detects that dpkg is present at configure time then it
enables the support for deb files. Users can explicitly enable or
disable that support by passing --enable-deb or --disable-deb to
configure.
* config.h.in: Define WITH_DEB and WITH_RPM pre-processor macros.
* configure.ac: Add --enable-{rpm,deb} switches. Check for
rpm2cpio and cpio programs, unless --disable-rpm was provided. If
they are found and if --enable-rpm=auto was provided, then
consider that --enable-rpm=yes was provided. In that case, set
the WITH_RPM macro to 1. Otherwise, undefine that macro.
Similarly, check for dpkg unless --disable-deb was provided. If
it's found and if --enable-deb=auto was provided, consider that
--enable-deb=yes was provided. In that case, set the WITH_DEB
macro to 1. Otherwise, undefine that macro. Define the
ENABLE_RPM and ENABLE_DEB conditional automake variables, if the
rpm resp. deb support is enabled. Emit a notice about the rpm and
deb features being enabled or not, at the end of the configure
process.
* tests/test-diff-pkg.cc: Include the config.h header.
(in_out_spec): Guard rpm tests by the WITH_RPM macro. Similarly,
guard deb tests by the WITH_DEB macro.
* tools/abipkgdiff.cc: Include the config.h header.
(extract_rpm): Guard this function definition with the WITH_RPM
macro.
(extract_deb): Guard this function definition with the WITH_DEB
macro.
(extract_package): Guard the handling of rpm packages with the
WITH_RPM macro and the handling of deb package with the WITH_DEB
macro. If a package not-support package format is encountered,
emit an appropriate error message and error out.
Matthias Klose [Fri, 7 Aug 2015 08:48:17 +0000 (10:48 +0200)]
Add support for .deb files to abipkgdiff
This lets abipkgdiff compare debian binary packages.
The patch contains test cases for debian package with split debug info
that is referenced by the build-id scheme. These test cases come from
the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792,
more particularly from the attachment
https://sourceware.org/bugzilla/attachment.cgi?id=8516.
* include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB.
* tools/abipkgdiff.cc (extract_deb): New.
(extract_package, main): Handle FILE_TYPE_DEB.
* src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB.
(guess_file_type): Detect FILE_TYPE_DEB.
* tools/abidiff.cc (main): Handle FILE_TYPE_DEB.
* tools/abilint.cc (main): Handle FILE_TYPE_DEB.
* tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb:
Input debian debug info package; to be compared by the test
harness runtestdiffpkg.
* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb:
Input debian package; to be compared by the test harness
runtestdiffpkg.
* tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb:
Input debug info package
* tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb:
Input debian package; to be compared by the test harness
runtestdiffpkg.
* 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:
Reference output for the comparison of the packages above.
* tests/data/Makefile.am: Add the new files above to the source distribution.
* tests/test-diff-pkg.cc (in_out_specs): Add the input packages
above to the set of files to be compared by this test harness.
Dodji Seketeli [Fri, 14 Aug 2015 11:21:33 +0000 (13:21 +0200)]
Do not remove api and website source files by accident
When the root source dir is used as root build dir, make clean can
remove the content of ${abs_builddir}/api which is then equal to
${abs_srcdir}/api. Oops. This patch fixes this.
* doc/Makefile.am: Do not remove the entirety of the build dir of
doxygen for the apidoc and the website as these can be also the
source dirs. Rather, remove that is under the html/ sub-directory
of the build dir, as this is always generated by doxygen.
Dodji Seketeli [Thu, 13 Aug 2015 15:21:13 +0000 (17:21 +0200)]
Add an abipkgdiff --fail-no-dbg command line option
* tools/abipkgdiff.cc (options::fail_if_no_debug_info): New data
member.
(options::options): Initialize it.
(display_usage): Document it.
(compare): If the user asked for it, fail if the we couldn't file
the debug info for the corpus files being compared.
Dodji Seketeli [Thu, 13 Aug 2015 21:12:03 +0000 (23:12 +0200)]
Add -h and -d option shortcuts to abidw
Added a -h option shortcut for the --help option and a -d option
shortcut for the --debug-info-dir option, to the abidw program.
* tools/abidw.cc (display_usage): Added a documentation string.
(parse_command_line): Parse the new -h and -d shortcuts.
* doc/manuals/abidw.rst: Update the manual.
Dodji Seketeli [Thu, 13 Aug 2015 21:07:24 +0000 (23:07 +0200)]
Add a -h option shortcut to abidiff
Added a -h shortcut for --help to the abidiff program.n
* tools/abidiff.cc (display_usage): Add documentation for the new
switch.
(parse_command_line): Parse the -h option.
* doc/manuals/abidiff.rst: Update the manual.
Dodji Seketeli [Sun, 9 Aug 2015 00:11:17 +0000 (02:11 +0200)]
Bug 18791 - libabigail fails to read the output of abidw
The reader fails to set the access specifier for a member type. Fixed
thus.
* src/abg-reader.cc (read_context::get_scope_for_node): Take an
access_specifier output parameter to set the access specifier of
the current node in its scope. Update the function to set the
access_specifier.
(read_context::build_or_get_type_decl): Adjust to set the access
specifier of the type we are building, in case it's a member type.
* tests/data/test-abidiff/test-PR18791-v{0,1}.so.abi: New test input files.
* tests/data/test-abidiff/test-PR18791-report0.txt: New test
output reference.
* tests/data/Makefile.am: Add the new test material to the source
distribution.
* tests/test-abidiff.cc (specs): Add the new test inputs to the set of
input files this test harness has to run over.
Dodji Seketeli [Thu, 6 Aug 2015 11:56:48 +0000 (13:56 +0200)]
Add --no-added-syms to abipkgdiff
With this new option the tool ignores added functions, variables and
their symbols.
* tools/abipkgdiff.cc (options::show_added_syms): New data member.
(options::options): Initialize it.
(parse_command_line): Parse the new --no-added-syms option and set
the options::show_added_syms flag accordingly.
(display_usage): Add a help string for the new option.
(set_diff_context_from_opts): Set the diff context according to
the state of the new options::show_added_syms flag.
* doc/manuals/abipkgdiff.rst: Add manual entry for the new
--no-added-syms options.
* tests/data/test-diff-pkg/test-rpm-report-5.txt: New test
reference input file.
* tests/data/Makefile.am: Add the new file above to source
distribution.
* tests/test-diff-pkg.cc (InOutSpec::prog_options): New data
member.
(in_out_specs): Adjust. Add a new input to run the test again
with --no-added-syms.
(main): Adjust to pass the program options contained in
InOutSpec::prog_options to abipkgdiff.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
fixup! Add --no-added-syms to abipkgdiff
Dodji Seketeli [Thu, 6 Aug 2015 11:36:52 +0000 (13:36 +0200)]
Update diff stats when added symbols are removed from change report
Until now, when added symbols were removed from the diff output, the
diff stat was not properly updated. This patch fixes that.
* include/abg-comparison.h (diff_context_wptr)
(corpus_diff::diff_stats_sptr): New typedefs.
(corpus_diff::diff_stats::diff_stats): Make this constructor take
a diff_context_sptr. Make the default constructor private.
* src/abg-comparison.cc (corpus_diff::diff_stats::priv::ctxt_):
New data member. This is a weak pointer to a diff_context.
(corpus_diff::diff_stats::priv::priv): Take a diff_context_sptr
and initialize the weak pointer ctxt_ to it.
(corpus_diff::diff_stats::priv::ctxt): New accessor to the
diff_context hold by the diff_stats.
(corpus_diff::diff_stats::{num_removed_func_filtered_out,
num_added_func_filtered_out, num_removed_vars_filtered_out,
num_added_vars_filtered_out, num_removed_func_syms_filtered_out,
num_added_func_syms_filtered_out,
num_removed_var_syms_filtered_out,
num_added_var_syms_filtered_out}): If the user asked for the added
[or removed] variables/functions/symbols to be ignored, the
accessors for the number of filtered added/removed variables/functions/symbols
return the total number of added/removed
variables/functions/symbols; that is, say that *all* added/removed
variables/functions/symbols got filtered out.
(corpus_diff::priv::diff_stats_): Turn this data member into a
[shared] pointer to diff_stats.
(corpus_diff::priv::filters_and_suppr_applied_): Remove this data
member. Now that diff_stats_ is a pointer, we don't need this
boolean anymore.
(corpus_diff::apply_filters_and_suppressions_before_reporting):
Adjust to the fact that filters_and_suppr_applied_ is gone, and
that diff_stats_ is now a pointer.
(corpus_diff::report): Control un-referenced added symbols
reporting with
diff_context::show_added_symbols_unreferenced_by_debug_info()
Make applying supp specs through pointer access look through typedefs
Consider the declaration of the exported function bar() below:
struct _OpaqueType {int member;};
typedef struct _OpaqueType Type;
void bar(Type*);
Once the *definition of struct _OpaqueType and bar() are compiled into
a shared library, if a layout change happens to struct _OpaqueType,
then abidiff rightfully reports that bar() is impacted by the layout
change to struct _OpaqueType.
But then, the following suppression specification won't silence the
ABI change report:
[suppress_type]
name = _OpaqueType
type_kind = struct
accessed_through = pointer
This is because strictly speaking, it's not struct _OpaqueType that is
accessed through a pointer, from function bar(); it's the type 'Type',
(which is a typedef of struct _OpaqueType) that is accessed though a
pointer.
But then, as 'Type' and 'struct _OpaqueType' are the same type (modulo
the typedef), this behaviour is not super useful. It would be more
interesting if the suppression specification could silence the ABI
change report.
And this is what this patch does.
* include/abg-comparison.h (type_suppression::suppresses_type):
Declare new member function.
(get_typedef_diff_underlying_type_diff): Declare new function.
* include/abg-fwd.h (get_typedef_underlying_type): Likewise.
* src/abg-comparison.cc (type_suppression::suppresses_type):
Define new member function.
(get_typedef_diff_underlying_type_diff): Define new function.
(type_suppression::suppresses_diff): After looking through the
different kind of access methods, use the new
type_suppression::suppresses_type(), rather than doing lots of
stuff ourselves here. But then, if the suppression doesn't apply
to the subjects of the diff, look through typedefs and try to
apply the suppression again.
* src/abg-ir.cc (get_typedef_underlying_type): Define new
function.
* tests/data/test-diff-suppr/libtest25-typedef-v{0,1}.so: New
binary test input files.
* tests/data/test-diff-suppr/test25-typedef-v{0,1}.c: Source code
for the binary test input files above.
* tests/data/test-diff-suppr/test25-typedef-report-{0, 1}.txt: New test
input files.
* tests/data/test-diff-suppr/test25-typedef-suppr-0.txt: New test
input file.
* tests/data/Makefile.am: Add the new test material to the source
distribution.
* tests/test-diff-suppr.cc (in_out_specs): Add the test inputs
above to the set of test inputs this harness has to run over.
Make abipkgdiff erase the *parent* directory of temporary files
abipkgdiff was erasing the temporary files created by it wasn't
erasing the parent directory containing them. Fixed thus.
* tools/abipkgdiff.cc
(erase_created_temporary_directories_parent): New static function.
(compare): After comparison, erase the temporary parent directory
as well.
Make the name of the removed variable section be consistent
The removed functions section is introduced by the string "Removed
functions", whereas the removed variables section is introduced by the
string "Deleted variables". This patch makes the latter be "Removed
variables" just like for the functions.
* src/abg-comparison.cc (corpus_diff::report): Introduce the
section of removed variables with the string "Removed variable",
rather than with the string "Deleted variable".
* tests/data/test-abicompat/test2-var-removed-report-0.txt: Adjust.
* tests/data/test-diff-suppr/test18-suppr-removed-var-report-0.txt: Likewise.
* tests/data/test-diff-suppr/test18-suppr-removed-var-report-3.txt: Likewise.
* tests/data/test-diff-suppr/test18-suppr-removed-var-report-5.txt: Likewise.
Consider default symbol versions when computing added/removed fns/vars
When computing the set of added function or variable symbols, if a
symbol S with no version symbol was present in a given corpus and that
symbol gained a *DEFAULT* version V in the second corpus, we should
not consider that a new symbol S was added (and that the former S was
removed) because:
1/ S was already present in the first corpus
2/ applications linked to the first corpus and that were using S
(with no version) there, will automatically use the S with version V
in the second corpus, without needing any re-linking; the
power of symbol versioning!
Rather, it's just that S gained a default symbol version.
This patch implements that.
* include/abg-corpus.h (corpus::{lookup_function_symbol,
lookup_variable_symbol}): Take a elf_symbol::version object,
rather than a string representing the version. Add an overload
that takes an elf_symbol.
* src/abg-corpus.cc (find_symbol_by_version): New static function.
(corpus::{lookup_function_symbol, lookup_variable_symbol}): Take a
elf_symbol::version object, rather than a string representing the
version. Add an overload that takes an elf_symbol. If the looked
up symbol has no version and if the corpus contains a symbol with
the same name and with a default version, then return that latter
symbol if the corpus doesn't contain a symbol with the same name
and empty version.
* src/abg-comparison.cc
(class_diff::ensure_lookup_tables_populated): Adjust.
(corpus_diff::priv::ensure_lookup_tables_populated): Before
deciding that a symbol has been added, if the symbol has a default
version, make sure no symbol with the same name and without
version was present in the former corpus. Similarly, before
deciding that a symbol has been removed, if the symbol has no
version, make sure the latter corpus has no symbol with the same
name and with a default version.
* tests/data/test-diff-dwarf/test12-report.txt: Adjust. The
function should not be considered as added, because its symbol
(and version) was already present in the former DSO.
It appears the comparison engine was counting more deleted variables
than necessary, due to a thinko. Fixed thus.
* src/abg-comparison.cc
(corpus_diff::priv::ensure_lookup_tables_populated): Once we have
computed a set of potentially deleted variables that turned out to
contain variables that were actually *NOT* deleted, really take
these into account by removing these false positives from the set
of deleted *variables*. We were trying to delete these from the
set deleted *functions*; woops, I guess this was a copy & paste
error.
* src/abg-ir.cc (type_has_non_canonicalized_subtype): Once the
type has been traversed, just test if the visitor has accumulated
the 'has_non_canonical_type' property.
* include/abg-ir.h (struct ir_node_visitor): Fix the wording of
the comment of this type.
* src/abg-dwarf-reader.cc (build_ir_node_from_die): Fix the
filling of the text of the comment of the code that chooses to
perform early canonicalizing.
Adding member type doesn't reset declaration-only-ness of a class
When reading DWARF, a declaration-only class was loosing its
declaration-only-ness just because a member type was being added. Bad
things was then happening next because that (normally
declaration-only) class was then considered as being suitable for
early canonicalizing, while it wasn't (yet), in reality. Its
canonicalizing should have been deferred.
This issue was spotted when comparing
kdebase-workspace-4.3.4-29.el6_6.x86_64.rpm and,
kdebase-workspace-4.3.4-30.el6_6.x86_64.rpm, using their associated
debug info. The issue was happening precisely when comparing their
usr/lib64/kde4/kwin4_effect_builtins.so DSOs, precisely; it was
leading to a crash.
* src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir):
Adding a new member type shouldn't remove the
declaration-only-ness of the class.
Extract all packages for a given run of abipkgdiff under the same temp dir
This patch extracts all packages for a given run of abipkgdiff under
the same temporary directory, cluttering /tmp less.
To do this, the patch makes accesses of data members of the 'package'
type go through accessor functions only. Then the accessor for the
parent directory of all extracted package does the job of computing
the path to that parent directory in a way that makes it unique, per
thread.
* tools/abipkgdiff.cc (package::{<all data members>}): Make the
data members be private. Make their names end with an underscore.
(package::extracted_package_parent_dir_path): Remove.
(package::extracted_package_dir_path): Rename into
package::extracted_dir_path_.
(package::extracted_packages_parent_dir): New static member
function, accessor.
(package::package): Adjust to the new names of the data members.
Call the new package::extracted_package_parent_dir() static member
function to initial the package::extracted_dir_path_ data member.
(package::{path, extracted_dir_path, type, is_debug,
path_elf_file_sptr_map, debug_info_package}): New accessors for
the data members.
(package::{erase_extraction_directory,
erase_extraction_directories}): Adjust.
(erase_created_temporary_directories)
(create_maps_of_package_content)
(extract_package_and_map_its_content, prepare_packages, compare)
(main): Adjust.
Sometimes, for debugging purposes it can be very handy to inspect the
content of the packages as seen by the tool. This patch thus adds a
new --keep-tmp-files options so that users can inspect the content of
packages that were extracted.
* tools/abipkgdiff.cc (options::keep_tmp_files): New data member.
(options::options): Initialize it.
(display_usage): Display a usage string for the new
--keep-tmp-files option.
(parse_command_line): Parse the new --keep-tmp-files option.
(compare): Do not erase temporary directories if the users asked so.
* doc/manuals/abipkgdiff.rst: Document the new --keep-tmp-files
options.
With this patch abipkgdiff now shows the linkage names of
added/removed functions and variables. In addition, there now is a
--no-linkage-name option to avoid seeing linkage names.
* doc/manuals/abipkgdiff.rst: Document the new --no-linkage-name
options.
* tools/abipkgdiff.cc (options::show_linkage_names): New data
member.
(options::options): Initialize it.
(display_usage): Display a usage string for --no-linkage-name.
(parse_command_line): Parse the --no-linkage-name option.
(set_diff_context_from_opts): Set the diff context accordingly.
* tests/data/test-diff-pkg/test-rpm-report-0.txt: Adjust.
* tools/abipkgdiff.cc (options::show_added_binaries): New data
member.
(options::options): Initialize it.
(display_usage): Add a help string for --no-added-binaries.
(parse_command_line): Parse the new --no-added-binaries option.
(compare): Do not show added binaries if the user doesn't want to.
* doc/manuals/abipkgdiff.rst: Document the new --no-added-binaries
option.
With this patch, abipkgdiff returns the same exit code as abidiff.
It's zero if there is no ABI change, and non-zero if there are ABI
changes. The exact value depends on the kind of changes that is
detected.
* tools/abipkgdiff.cc (compare): Return an instance
abigail::tools_utils::abidiff_status, just like what we do in
abidiff.
* doc/manuals/abipkgdiff.rst: Document the new exit code.
Fix logic of determining if changes happened in abidiff
Now that we can easily check if the diff between two corpora carries
net changes (i.e, changes after applying suppression specifications)
we can simplify the logic of determining if the corpora have
"worthwhile" changes, in abidiff.
* tools/abidiff.cc (main): Simplify the logic when determining if
the comparison between two corpora yields worthwhile changes.
Add a new corpus_diff::has_net_changes() entry point
This entry point is to test if there are still ABI changes between two
corpora after applying suppression specifications.
* include/abg-comparison.h (corpus_diff::has_net_changes): Declare
new member function.
* src/abg-comparison.cc (corpus_diff::has_net_changes): Define it.
While looking further in the issue Sinny Kumari reported, I realized
that the weak mode wasn't working in that example either.
It turned out that synthesizing qualified types was not working
because we were just looking them up in the binary, rather than
looking up the un-qualified underlying type and then synthezing the
resulting qualified type.
This patch just does that.
* include/abg-fwd.h
(synthesize_type_from_translation_unit): Declare new function.
(synthesize_function_type_from_translation_unit): Make the
translation_unit parameter non-const because the function needs to
bind the life time of the synthesized function to the life time of
the translation unit. Make this function be a friend of
abigail::ir::translation_unit.
(synthesize_function_type_from_translation_unit):
* src/abg-ir.cc (translation_unit::priv::synthesized_types_): New
data member.
(synthesize_type_from_translation_unit): Define new function.
(synthesize_function_type_from_translation_unit): Make the
translation_unit parameter non-const. If the return is void, then
take that in account carefuly. Rather than just looking up the
type of parameters and return value, synthesize them too,
especially when they are qualified types. Bind the life time of
the synthesized function type to the lifetime of the translation
unit.
* tests/data/test-abicompat/test7-fn-changed-report-1.txt: New
test reference output.
* tests/test-abicompat.cc (in_out_spec): Run the harness on the
exisiting test7-fn-changed-app and libtest7-fn-changed-libapp-v1
but in weak mode this time.
Fix computing the set of exported functions and varible symbols
Sinny Kumari reported that abicompat is failing to report ABI changes
on a library linked to a small test program. It turned out that the
code that compute if a given exported function is to be kept by
looking at the white list of symbols to keep has a bug in which the
versions of the symbols of the white list were not being reset as they
should. Fixed thus.
* src/abg-ir.cc (elf_symbol::get_name_and_version_from_id): Always
set the version and name of the symbol.
* src/abg-corpus.cc
(corpus::exported_decls_builder::{keep_wrt_id_of_fns_to_keep,
keep_wrt_id_of_vars_to_keep}): Reset the symbol name *and* version
before passing it. This is redundant with the fix in
elf_symbol::get_name_and_version_from_id() that always set the
symbol name and version now, but I felt it makes it easier to
understand the fix overall.
* tests/data/test-abicompat/libtest7-fn-changed-libapp-v{0,1}.so:
New test input binaries.
* tests/data/test-abicompat/test7-fn-changed-app: Likewise.
* tests/data/test-abicompat/test7-fn-changed-{app, libapp-v0,
libapp-v1}.c: Source code of the binary test inputs above.
* * tests/data/test-abicompat/test7-fn-changed-{libapp-v0,
libapp-v1}.h: Likewise.
* tests/data/test-abicompat/test7-fn-changed-report-0.txt: Test
input.
* tests/data/Makefile.am: Add the new test material above to
source distribution.
* tests/test-abicompat.cc (int_out_specs): Add the test inputs
above to the set of inputs this test harness has to run over.
We were using the unsafe tmpnam function in abilint. This patch
creates a helper type abigail::tools_utils::temp_file that does away
with the use tmpnam in abilint.
* include/abg-tools-utils.h (abigail::tools_utils::temp_file):
Declare new type.
(abigail::tools_utils::temp_file_sptr): New typedef.
* src/abg-tools-utils.cc (temp_file::priv): Define new type.
(temp_file::{temp_file, is_good, get_path, get_stream, create}):
Define new member functions.
* tools/abilint.cc (main): Do not use tmpnam anymore. Use the new
abigail::tools_utils::temp_file type instead.
Try to avoid a race condition when abipkgdiff extracts packages.
abipkgdiff extracts the content of the first package in a directory
named <tmpdir>/package1 and the content second package in
<tmpdir>/package2. If two independant instances of abipkgdiff are
launched at the same time, they are going to walk on each others'
toes, to say the least.
This patch extracts the content of each package in directory named
<tmpdir>/<randomname>/package1, where randomname is supposed to be a
random number, and so should be unique, most of the time.
I guess we should try harder to generate a randomname that is unique
when we see that the directory <tmpdir>/<randomname> exists already,
but for now, what we have is good enough, or at least better than what
we have had so far.
* include/abg-tools-utils.h (get_random_number)
(get_random_number_as_string): Declare new functions.
* src/abg-tools-utils.cc (get_random_number)
(get_random_number_as_string): Define them.
* tools/abipkgdiff.cc
(package::extracted_package_parent_dir_path): New data member.
(package::package): Initialize
package::extracted_package_parent_dir_path to
<tmpdir>/<randomname>, with randomname being a random number
represented as a string.
(extract_rpm): Make sure to create a hierarchy of directories, not
just a directory.
On changed fn, show symbol info when name is different from linkage name in C
In change reports for function sub-type changes, for the C language,
when the name of the function is different from its linkage name, even
when the function symbol has no aliases, show the symbol information
of the function.
* include/abg-ir.h (translation_unit::language): New enum type.
(translation_unit::{get_language, set_language}): Declare new
accessors.
(translation_unit_language_to_string)
(string_to_translation_unit_language, is_c_language)
(is_cplus_plus_language): Declare new functions.
* src/abg-ir.cc (translation_unit::priv::language_): New data
member.
(translation_unit::priv::language_): Initialize it.
(translation_unit::{set_language, get_language}): Define new
member functions.
(translation_unit_language_to_string)
(string_to_translation_unit_language, is_c_language)
(is_cplus_plus_language): Define new functions.
* src/abg-dwarf-reader.cc (dwarf_language_to_tu_language): New
static function.
(build_translation_unit_and_add_to_ir): Read the language of the
translation unit.
* src/abg-comparison.cc (corpus_diff::report): When reporting a
change in a function sub-type, if we are in C language translation
unit, if the function name is different from its linkage name,
even if the symbol doesn't have any alias, show symbol
information.
* src/abg-reader.cc (read_translation_unit_from_input): Read the
'language' property of the translation unit, if present.
* src/abg-writer.cc (write_translation_unit): Write the 'language'
property to the translation unit, if present.
* tests/data/test-read-dwarf/test0.abi: Adjust for the new
'language' property of the 'abi-instr' element.
* tests/data/test-read-dwarf/test1.abi: Likewise.
* tests/data/test-read-dwarf/test2.so.abi: Likewise.
* tests/data/test-read-dwarf/test3.so.abi: Likewise.
* tests/data/test-read-dwarf/test4.so.abi: Likewise.
* tests/data/test-read-dwarf/test5.o.abi: Likewise.
* tests/data/test-read-dwarf/test6.so.abi: Likewise.
* tests/data/test-read-dwarf/test7.so.abi: Likewise.
* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi:
Likewise.
* tools/abipkgdiff.cc (options::suppressions): New data member.
(set_diff_context_from_opts): Set the suppression specifications
provided by the user to the diff context.
(parse_command_line): Parse the --suppressions and --suppr command
line options.
* doc/manuals/abipkgdiff.rst: Document the --suppressions and
--suppr options.
Support file_name_regexp and soname_regexp in supp-specs
With this patch it's now possible to express the soname or name of the binary
file that contains the ABI artifacts the suppression specifications
should apply to.
* include/abg-comparison.h (suppression_base::priv_): Make this
pimpl member protected.
(suppression_base::set_file_name_regex_str)
(get_file_name_regex_str, get_soname_regex_str)
(set_soname_regex_str): Declare new accessors.
(function_suppression::{suppresses_function,
suppresses_function_symbol}): Take a diff_context_sptr.
(variable_suppression::{suppresses_variable,
suppresses_variable_symbol}): Take a diff_context_sptr.
* src/abg-comparison.cc
(suppression_base::priv::{file_name_regex_str_, file_name_regex_,
soname_regex_str_, soname_regex_}): Define new data members.
(suppression_base::priv::get_file_name_regex_str)
(get_soname_regex_str): Define new member functions.
(suppression_base::set_file_name_regex_str)
(get_file_name_regex_str, get_soname_regex_str)
(set_soname_regex_str): Define new accessors.
(type_suppression::suppresses_diff): Evaluate file_name_regexp and
soname_regexp.
(read_type_suppression): Fix the reading of the "label" property.
Read the file_name_regexp and soname_regexp properties.
(function_suppression::{suppresses_function,
suppresses_function_symbol): Take a diff_context_sptr parameter.
Evaluate file_name_regexp and soname_regexp properties.
(function_suppression::suppresses_diff): Adjust for the api change
of function_suppression::suppresses_function().
(read_function_suppression): Read the file_name_regexp and
soname_regexp properties.
(variable_suppression::suppresses_variable): Take a
diff_context_sptr parameter and evaluate file_name_regexp and
soname_regexp properties.
(variable_suppression::suppresses_variable_symbol): Likewise.
(variable_suppression::suppresses_diff): Adjust for the api change
of variable_suppression::suppresses_variable().
(read_variable_suppression): Read the file_name_regexp and
soname_regexp properties.
(function_is_suppressed, variable_is_suppressed): Take a
diff_context_sptr parameter.
(corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars):
Adjust.
* doc/manuals/libabigail-concepts.rst: Document file_name_regexp
and soname_regexp in the manual.
* tests/data/test-diff-suppr/libtest24-soname-v{0,1}.so: New test
binary input files.
* tests/data/test-diff-suppr/test24-soname-report-{0,4}.txt: New
test input files.
* tests/data/test-diff-suppr/test24-soname-suppr-{0,4}.txt:
Likewise.
* tests/data/test-diff-suppr/test24-soname-v{0,1}.cc: Source code
of the binary test input files above.
* tests/data/Makefile.am: Add the new test material above to
source distribution.
* tests/test-diff-suppr.cc (in_out_spec): Add the new test inputs
to the set of tests this harness has to run over.
When evaluating the way the diff node has been reached, do not crash
on diff nodes that are pointer_diff to something else but a type diff,
because there can be pointers to distinct_diff nodes, for instance.
* src/abg-comparison.cc (type_suppression::suppresses_diff): When
evaluating the reach_kind property, do not crash on diff nodes
that are pointer_diff or reference_diff to something else but a
type diff.
When a binary cannot be analyzed by abipkgdiff, silently skip it
unless --verbose is used, in which case, display a message saying
that it couldn't be analyzed.
* tools/abipkgdiff.cc (compare): In the elf_file overload, do not
emit an error message when a binary could not be analyzed unless
--verbose was provided.
Just like what abidiff does, this patch avoids emitting redundant diff
report messages unless the user provides the --redundant switch.
* tools/abipkgdiff.cc (options::show_redundant_changes): New data
member.
(options::options): Initialize it.
(display_usage): Add a help string for the --redundant command
Line option.
(set_diff_context_from_opts): New static function.
(compare): Take the options variable. Set the diff context from
the options, especially if we should show redundant changes or
not. Use that diff context when comparing ABIs.
(parse_command_line): Parse the new --redundant command line
switch.
* doc/manuals/abipkgdiff.rst: Document the new --redundant option.
It turned out on some packages we are interested on comparing shared
libraries only. This patch adds that functionality by adding a new
--dso-only command line option to abipkgdiff.
* tools/abipkgdiff.cc (options::compare_dso_only): New data
member.
(options::options): Initialize it.
(display_usage): Display a little help string for it.
(create_maps_of_package_content): Take the option variable. Do
not compare non-dso files if the --dso-only option was provided.
(extract_package_and_map_its_content, prepare_packages, compare):
Take the option variable.
(parse_command_line): Parse the new --dso-only option.
* doc/manuals/abipkgdiff.rst: Add documentation for the new
--dso-only option.
* src/abg-dwarf-reader.cc (get_soname_of_elf_file): Better wording
of the apidoc of this function.
* tools/abipkgdiff.cc (verbose, elf_file_paths): Add apidoc for
these global variables.
(struct options, ): Add apidoc for these types.
(options::{erase_extraction_directory,
erase_extraction_directories}, display_usage, extract_rpm)
(erase_created_temporary_directories, extract_package)
(file_tree_walker_callback_fn, compare)
(create_maps_of_package_content)
(extract_package_and_map_its_content, prepare_packages, compare)
(parse_command_line): Add apidoc for these functions.
Add tests for the abipkgdiff tool. The tests runs abipkgdiff on RPM
packages. RPMs for test data are taken from Fedora koji build with
build id - 106158 and 648058
* tests/Makefile.am: Build new runtestdiffpkg regression test
* tests/data/Makefile.am: Add new test files to source
* tests/data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64.rpm:
Test data for abipkgdiff tool
* tests/data/test-diff-pkg/dbus-glib-0.80-3.fc12.x86_64.rpm: Likewise
* tests/data/test-diff-pkg/dbus-glib-debuginfo-0.104-3.fc23.x86_64.rpm:
Likewise
* tests/data/test-diff-pkg/dbus-glib-debuginfo-0.80-3.fc12.x86_64.rpm:
Likewise
* tests/data/test-diff-pkg/test-rpm-report-0.txt: Expected test output
* tests/data/test-diff-pkg/test-rpm-report-1.txt: Likewise
* tests/data/test-diff-pkg/test-rpm-report-2.txt: Likewise
* tests/data/test-diff-pkg/test-rpm-report-3.txt: Likewise
* tests/data/test-diff-pkg/test-rpm-report-4.txt: Likewise
* tests/test-diff-pkg.cc: New file
* doc/manuals/abipkgdiff.rst: New manual file.
* doc/manuals/libabigail-tools.rst: Refer to the manual for
abipkgdiff.
* doc/manuals/Makefile.am: Add the new manual file to source
distribution.
* doc/manuals/conf.py: Add the manual for abipkgdiff to section 1.
* src/abg-dwarf-reader.cc (get_soname_of_elf_file): Better wording
of the apidoc of this function.
* tools/abipkgdiff.cc (verbose, elf_file_paths): Add apidoc for
these global variables.
(struct options, ): Add apidoc for these types.
(options::{erase_extraction_directory,
erase_extraction_directories}, display_usage, extract_rpm)
(erase_created_temporary_directories, extract_package)
(file_tree_walker_callback_fn, compare)
(create_maps_of_package_content)
(extract_package_and_map_its_content, prepare_packages, compare)
(parse_command_line): Add apidoc for these functions.
* abipkgdiff.cc (get_soname_of_elf_file): Fix spacing.
* tools/abipkgdiff.cc (elf_file_paths): Make this global variable
static.
(extract_rpm): Rename parameter pkg_path name into package_path.
Remove the last direct fiddling with ELF from abipkgdiff.cc
Directly using elfutils from abipkgdiff.cc feels like a taping into
the wrong abstraction layer from this level. So this patch moves the
determination of the type of elf file into abg-dwarf-reader.cc and
uses it from there. The patch also simplifies the instantiation of
types elf_file and package, from abipkgdiff.cc.
* abg-dwarf-reader.h (enum elf_type): Move this declaration here
from abipkgdiff.cc to here.
(get_type_of_elf_file): Declare this new function.
(get_soname_from_elf): Change this to take a path to the elf file
rather than a Elf* handler. So now to use this, the user doesn't
have to get her hand dirty with elfutils.
* src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to
take a path to the elf file rather than a Elf* handler.
(elf_file_type): Move this static function here, from
abipkgdiff.cc.
(get_type_of_elf_file): New function. This has been factorized
out of create_maps_of_package_content() in abipkgdiff.cc.
* tools/abipkgdiff.cc (class elf_file): Changed struct elf_file
into this. Make the default constructor private.
(elf_file::elf_file): Change the constructor to just take the path
to the elf_file. The base name, soname and elf file type are now
computed from the path file, in the constructor. This makes
instantiation much much easier from the point of view of the user
of the type.
(struct abi_diff): Renamed struct abi_changes into this.
(abi_diff::has_changes): Define new member function.
(abi_diffs): Remove this global variable.
(package::package): Remove the elf file type from the set of
parameters of this constructor. Rather, compute that elf file
type from the path to the elf file, in the constructor. Again,
this eases the use of the type.
(elf_file_type): Remove this from here, as it got moved to
abg-dwarf-reader.cc.
(compare): In the elf_file overload, return true if the comparison
yields ABI changes.
(create_maps_of_package_content): Do not fiddle with elfutils
stuff here. Rather, just instantiate elf_file and the analyzing
of the file magically happens.
(compare): Make the package overload take an abi_diff as output
parameter, rather than populating a global variable in return.
(compare): Add an other overload for package that doesn't take the
abi_diff as output parameter and write it in terms of the previous
one.
(main): Adjust as the instantiation of package is now simpler.
It turned out it's important to be able to see what abipkgdiff is
actually doing. This patch adds a --verbose option that emits many
useful information about the tool's progress.
* tools/abipkgdiff.cc (verbose): Add a new global variable.
(package::erase_extraction_directory, extract_rpm, compare)
(create_maps_of_package_content): Emit verbose information.
(parse_command_line): Parse the --verbose option.
Use the library to implement ABI comparison in abipkgdiff
Until now, abipkgdiff was spawning a process running the 'abidiff'
command line tool to perform ABI comparison on binaries. This helped
in sketching what was possible with this tool. However, it's
sub-optimal in a final setup so this patch uses the libabigail library
to perform that comparison.
* tools/abipkgdiff.cc (compare): In the overload for elf_file, use
abigail::comparison::compute_diff() to compare the ABI of two
corpora. The corpora themselves is read using
abigail::dwarf_reader::read_corpus_from_elf(). This cleans up the
output of the tool because nothing is emitted to standard output
if the two ABI corpora compares equal.
Fix several string passing issues in abipkgdiff.cc
A number of functions have string parameters passed by value. Ooops.
They must be passed by reference.
Fixed thus.
* tools/abipkgdiff.cc (elf_file::elf_file): Pass the strings by
reference. Also, change the order of the parameters; all the
strings are passed first, then the elf_type is passed last.
(package::package): Likewise, pass the strings by reference, not
by value.
(create_maps_of_package_content): Adjust for the change in
parameters order of elf_file::elf_file.
Move get_soname() function to abg-dwarf-reader.h/cc
Initially, fetching SONAME from a given DSO file was done in
abipkgdiff.cc. But, this function fits better when defined in
abg-dwarf-reader.cc in order to make it usable by other tools if
needed. For consistancy, get_soname() function has been renamed to
get_soname_from_elf().
* include/abg-dwarf-reader.h (get_soname_from_elf): Declare
new function
* src/abg-dwarf-reader.cc (get_soname_from_elf): Define new
function
* tools/abipkgdiff.cc (get_soname): Remove function
(pkg_diff): Call get_soname_from_elf() instead of get_soname()
This patch introduces many changes that should hopefully improve
legibility and ease of maintenance. Here is a list of the topic of
the changes:
* Avoid using shortened names when the line is not too long.
* Use shared_ptr when possible.
* When a function parameter is not meant to be nil, do not pass it
as a pointer; rather, pass it as a reference.
* Avoid doing things that can "fail" in a destructor; e.g, spawning
a process. Also, it's not common practise to cleanup a resource in a
type destructor, when that resource has not been created in one of the
member functions of the type. It eases maintenance when resource
creation and cleanup is performed at the same logical level.
* tools/abipkgdiff.cc (option::package{1,2}): Rename
option::pkg{1,2} into this, to increase legibility.
(option::debug_package{1,2}): Likewise, rename
option::debug_pkg{1,2} into this.
(elf_file::~elf_file): Do not "delete this" in a destructor. This
leads to double free. It's when someone invokes the "delete"
operator on a pointer to the object that the destructor of the
object is executed automatically; so if in the destructor the
delete operator is called again, bad things are going to happen.
As the destructor is now empty, remove it altogether.
(elf_file_sptr): New typedef for shared_ptr<elf_file>.
(package::path): Rename package::pkg_path into this, for better
legibility.
(package::extracted_package_dir_path): Rename
package::extracted_pkg_dir_path into this.
(package::type): Rename package::pkg_type into this.
(package::is_debug_info): Rename package::is_debuginfo_pkg into
this.
(package::path_elf_file_sptr_map): Rename
package::dir_elf_files_map into this because this is a map of
path -> elf_file_sptr. Also, now the value of the map element is
a elf_file_sptr, no more an elf_file*.
(package::debug_info_package): Rename package::debuginfo_pkg into
this.
(package::package): Adjust for the changes above.
(package::{erase_extraction_directory,
erase_extraction_directories}): New member functions.
(elf_file_paths): Renamed dir_elf_files_path into this.
(erase_created_temporary_directories)
(create_maps_of_package_content)
(extract_package_and_map_its_content, prepare_packages): New
static functions.
(get_soname, elf_file_type, extract_rpm): Make this static.
(extract_package): Take a const package& rather than a
package_sptr to express that the function really expects a non-nil
object by reference (not by copy) and that the object won't be
modified. Using a reference removes the possibility that the
pointer could be nil, causing crashes in the code where
parameter->something was used. Now only parameter.something can
be used, so no crash possible there. This is more solid code.
(file_tree_walker_callback_fn): Rename callback() into this. It
makes the code more legible and kind of 'self-documented'. At
least you get the hint that this is a callback function for some
file tree walking (ftw) function. Adjust for the relevant names
renaming above.
(compare): Rename compute_abidiff into this; again, this increases
legibility; at least at the point of use of this function. Rename
compare_package() into a an overload of compare() as well.
compare_package() used to take a vector of packages. It was hard
to guess by reading the signature of the function, which element
of the vector is expected to be the first vector of the
comparison, which one is to be the second, etc. Now, this
function takes two packages, named first_package and
second_package. That is more "typed"; that is, the signature is
more meaningful. Greater legibility, hopefully. And in the body
of the function, the debug information packages are now accessed
using the package::debug_info_package data member. Again, this is
less surprising, I believe. Also, explicitly erase the temporary
files that were created during this comparison. All this
simplifies the logic of this function, hopefully.
(parse_command_line): Make this static. Add new --d1 and --d2
command line switches that are shortcuts of --debug-info-pkg1 and
--debug-info-pkg2. Adjust this function for the relevant name
changes above. Make lines be shorter than 80 characters.
(main): Do not create any vector of parameters anymore as the
compare_packages() function don't take any vector of parameter
anymore. Just instantiate first_package and second_package now.
Adjust for the relevant name changes above. This hopefully
simplifies the logic of this function.
Through the libabigail project, we try to:
1/ make function names start with a verb
2/ avoid shortening function names, *unless* longer names make the
current line exceed 80 characters per line.
We believe these rules improve legibility for people reading the code.
This patch slightly changes abipkgdiff.cc file to comply with the
above.
* tools/abipkgdiff.cc (extract_package): Renamed extract_pkg into
this because shortening 'package' into 'pkg' provides no
legibility improvement.
(compare_packages): Renamed pkg_diff() into this, so that the name
of the function starts with a verb, and the shortened 'pkg' word
is renamed back to the 'package' word. This way, the code almost
reads like normal English sentences with verbs and complement,
thus enhancing legibility and easing latter maintenance.
(main): Adjust for the changes above.
* tools/abipkgdiff.cc (display_usage): Fixed the typo in
'bi-pacakge.' Also, refer to 'package', not to 'bi-package' that
is surprising to the user at first.
(compute_abidiff): Shorten the size of the introductory line.
The compiler complains that in function callback(), parameters st and
flag are unused. In that case, C++ allows the name of the parameter
to be omitted; that makes the compiler complaint go away.
* tools/abipkgdiff.cc (callback): Remove the name of parameters st
and flag.
the compiler rightfully complains that the const qualifier on the
return type is useless. This is because the value is returned by copy
so the const-ness is not relevant.
End all branches of get_soname() finish with a return statement
The compiler complains that there are some branches in the
get_soname() function that don't end up with a return statement. For
instance, there is no return statement right before the end of the
function, in case the outermost for loop is not taken.
This patch fixes that by having just one return statement at the end
of the function.
* tools/abipkgdiff.cc (get_soname): Have just one return statement
at the end of this function.
Sinny Kumari [Fri, 19 Jun 2015 11:27:05 +0000 (16:57 +0530)]
Exclude processing symlink, display removed/added binaries between two packages
Removed binaries can also lead to ABI breakage if an applicating was using
it previously. So, display it in ABI change report. Also, looking for
ABI change in symbolic link files doesn't make sense. Now, we are not
looking into ABI changes in symlink binaries.
* tools/abipkgdiff.cc (abi_changes): Declare new struct
(callback): Exclude symbloic link file for durther processing
(compute_abidiff): Consider SONAME if exists as key in map instead
of binary name, else binary as key. Also, print if removed/added
binaries exist between packages
Sinny Kumari [Tue, 9 Jun 2015 08:25:19 +0000 (13:55 +0530)]
Stdout ABI changes if same binary found in both package
Now, abipkgdiff can take two rpm packages and optional corresponding
debug-info pacakges. It look for same binary in both rpm directory and
if found calls abdiff along with debug-info options to get ABI changes
between them.
* tools/abipkgdiff.cc (compute_abidiff): New function
tools/abipkgdiff.cc (pkg_diff): Iterate through list of binaries
in both package directory and call compute_diff function if
same binary found in both file.
tools/abipkgdiff.cc (main): Also consider debug-info directories
avilable in debu-info packages.
Sinny Kumari [Tue, 2 Jun 2015 07:03:54 +0000 (12:33 +0530)]
Save ELF files, their type and SONAME if exist for extracted packages
An RPM package may conatins binaries, source/header files, config files,
etc. For abi check we are interested only in ELF binary files. This commit
stores binary files from extracted RPM in a map whose key is
binary file basename and value is struct elf_file with memeber variable
name, path, soname, type
* tools/abipkgdiff.cc (elf_type): Declare new enum
(elf_file): Declare new struct
(package): Add member variable dir_elf_files_map
(get_soname): Define new function
(elf_file_type): Define new function
(extract_rpm): Iterate over extracted directory files
and filter ELF binary files along with their information
like name, soname, elf_type and save in dir_elf_files_map
Sinny Kumari [Tue, 26 May 2015 07:29:26 +0000 (12:59 +0530)]
Extract packages(RPMs) into temporary directories for further processing
Input pacakges need to extracted for further processing which includes
fecthing all files in extracted rpms and look for ELF files aginst
which abi diff is required. Pacakges will be extracted in system tmp
directory.
* tools/abipkgdiff.cc (struct package): Declare new struct
(package_sptr): Declare shared_ptr for struct package
(extract_rpm): Define new fuction to extract rpm package
(extract_pkg): Define new function to extract pacakge
(pkg_diff): Define new function to get ABI diff between
two packages
(main): Create new object of type pacakge for each binary
and debuginfo pacakge passed in commandline options
Sinny Kumari [Thu, 21 May 2015 07:38:32 +0000 (13:08 +0530)]
Guess RPM file type
To run abipkgdiff between two pacakges, it should know whether
input files are valid pacakge file or not. This patch detects RPM and SRPM
pacakge file type. abipkgdiff uses it to know whether input files are
valid RPM pacakge file or not.
* include/abg-tools-utils.h (file_type): Added member
FILE_TYPE_RPM and FILE_TYPE_SRPM
(operator<<): New function declaration.
* src/abg-tools-utils.cc (file_type): Detect RPM and
SRPM file type
(operator<<): New function definition
* tools/abidiff.cc (main): Check for RPM and SRPM
file type as well.
* tools/abilint.cci (main): Check for RPM and SRPM file
type as well.
* tools/abipkgdiff.cc (main): Check whether input files
to abipkgdiff are valid RPM files or not.
Sinny Kumari [Tue, 19 May 2015 12:10:06 +0000 (17:40 +0530)]
Initial skeleton of abipkgdiff tool
Motive of abipkgdiff tool is to provide abi changes between two
pacakges. Packages can be .rpm, .deb or archives. It also takes
optional debug-info package to support pacakges shipping separate
debug-info.
This commit set-up initial skeleton of abipkgdif tool consisting of
help and usage otions. It ensures pkgdiff tool compiles and run when
libabigail gets compiled as whole. Initially, we will add support for
ABI changes for two rpm packages. Further, support for other pacakging
format can be added.
* tools/Makefile.am: Include abipkgdiff.cc in compilation and
generate abipkgdiff binary.
* tools/abipkgdiff.cc: New file
Support reading binaries that do not have a symbol table
* src/abg-dwarf-reader.cc
(read_context::find_symbol_table_section): Allow returning a nil
pointer to symbol table.
(read_context::lookup_elf_symbol_from_index): Return an empty elf
symbol if we got a nil pointer to symbol table.
(read_context::load_symbol_maps): If no symbol table is found then
consider that the symbol maps loading failed.
* src/abg-comparison.cc (class_diff::report): Do not emit new line
unless the diff is to be reported.
* tests/data/test-diff-filter/test25-cyclic-type-report-0.txt: Adjust.
* tests/data/test-diff-filter/test26-qualified-redundant-node-report-0.txt: Adjust.
* tests/data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-1.txt:
: Adjust.
It turned out we need to read all XML ABI files that were still
emitting empty types (nothing) to represent void types, e.g, for
function returning void. So the type comparison code needs to accept
nil types again.
* src/abg-comparison.cc (compute_diff): In the overload of
type_base_sptr accept nil types.
Handle the life time of the map of canonical types
While working on something else, it turned out that we need to cleanup
(de-allocate) the map of canonical types when all the translation
units that own types are de-allocated. Otherwise, when new
translation units are created later, the types in the canonical types
map become unrelated to the types in these new translation units,
leading to memory management issues.
This patch introduces a "usage watchdog" which detects when no
translation unit uses the type system anymore. That usage watchdog is
then used in the destructor of the translation_unit type to
de-allocate the global data that is logically owned by by the type
system.
The patch also changes the API to read translation units and corpora
in a way that forces users to get a handle on the resulting shared
pointer.
* include/abg-ir.h (type_base::canonical_types_map_type): Move
this typedef into abg-ir.cc and out of the type_base namespace.
(type_base::get_canonical_types_map): Likewise.
* src/abg-ir.cc (canonical_types_map_type): New typedef that got
moved here from type_base::canonical_types_map_type.
(get_canonical_types_map): Likewise got moved here from
type_base::get_canonical_types_map. Made static in the process.
(class usage_watchdog): New type.
(usage_watchdog_sptr, usage_watchdog_wptr): New typedefs.
(get_usage_watchdog, get_usage_watchdog_wptr, ref_usage_watchdog)
(maybe_cleanup_type_system_data): New static functions.
(translation_unit::priv::usage_watchdog_): Add new data member.
(translation_unit::priv::priv): Get a reference on the usage
watchdog.
(translation_unit::priv::~priv): If the usage watchdog says that
the type system is not used, then cleanup the global data
logically owned by the type system.
* include/abg-dwarf-reader.h (read_corpus_from_elf): Make this
return a corpus and set the status by reference using a parameter.
* src/abg-dwarf-reader.cc (read_corpus_from_elf): Implement the
above.
* include/abg-reader.h (read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream): Remove the overloads that do
not return a translation_unit_sptr and that pass it as a
parameter. Only keep the overloads that return a
translation_unit_sptr, forcing users of the API to own a proper
reference on the resulting translation_unit pointer. That is
important to handle the life time of the global data of the type
system that need to be cleared when the last translation unit is
de-allocated.
* src/abg-reader.cc (read_translation_unit_from_input): Make this
return a translation_unit_sptr.
(read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream): Remove the overloads that do
not return a translation_unit_sptr and that pass it as a
parameter. Only keep the overloads that return a
translation_unit_sptr.
(read_to_translation_unit): Make this return a
translation_unit_sptr.
* tests/print-diff-tree.cc (main): Adjust.
* tests/test-diff-dwarf.cc (main): Likewise.
* tests/test-ir-walker.cc (main): Likewise.
* tests/test-read-dwarf.cc (main): Likewise.
* tests/test-read-write.cc (main): Likewise.
* tools/abicompat.cc (main): Likewise.
* tools/abidiff.cc (main): Likewise.
* tools/abidw.cc (main): Likewise.
* tools/abilint.cc (main): Likewise.