* 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>
The decl of a member variable which DIE is in the main debug info
section is being associated with the alternate debug info section,
just because the specification DIE of the variable is in the alternate
debug info section.
This patch associates the decl of a member variable with the same
debug info section as its DIE, not with the debug info section of its
specification DIE.
Note that I am not adding a regression test for this because the
reproducer RPMs given in the bug for this issue are too big and slow
to analyze.
* src/abg-dwarf-reader.cc (build_ir_node_from_die): Associate the
decl of the variable to the same debug info file (alternate or
not) as the DIE, not as its specification DIE.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
maybe_canonicalize_type aborts because the assertion that
read_context::lookup_type_from_die_offset should always return a type
is violated. read_context::lookup_type_from_die_offset is called on
the offset of a DIE of a type that is being constructed. The problem
is that that fonction only looks in the map of types that are fully
constructed.
This patch addresses the issue by making
read_context::lookup_type_from_die_offset look up class and function
types being constructed as well.
While doing that I had to add maps for class and function types being
constructed and that are in the alternate debug info section. I
adjusted the accessors for class and function types accordingly. The
code using those accessors was adjusted accordingly as well.
The patch also prevents maybe_canonicalize_type for DIEs which no type
was built for, in buid_ir_node_from_die. This is particularly for
DW_TAG_class_type and DW_TAG_structure_type DIEs.
* src/abg-dwarf-reader.cc
(read_context::{alternate_die_wip_classes_map_,
alternate_die_wip_function_types_map_}): New data members.
(read_context::lookup_type_from_die_offset): Lookup WIP class and
function types too.
(read_context::{die_wip_classes_map, die_wip_function_types_map}):
Take a flag saying if we should get the map for the alternate
debug info section or not.
(read_context::{is_wip_class_die_offset,
is_wip_function_type_die_offset}): Take a flagy saying if the DIE
is in the alternate debug info section or not.
(build_class_type_and_add_to_ir, build_function_type)
(maybe_canonicalize_type): Adjust.
(build_ir_node_from_die): Do not call maybe_canonicalize_type on
type DIEs which no type has been constructed for.
* tests/data/test-diff-pkg/gtk2-debuginfo-2.24.22-5.el7.i686.rpm:
New test input.
* tests/data/test-diff-pkg/gtk2-debuginfo-2.24.28-8.el7.i686.rpm:
Likewise.
* tests/data/test-diff-pkg/gtk2-immodule-xim-2.24.22-5.el7.i686.rpm:
Likewise.
* tests/data/test-diff-pkg/gtk2-immodule-xim-2.24.28-8.el7.i686.rpm:
Likewise.
* tests/data/test-diff-pkg/gtk2-immodule-xim-2.24.22-5.el7.i686--gtk2-immodule-xim-2.24.28-8.el7.i686-report-0.txt:
New test reference output.
* tests/data/Makefile.am: Add the new test material to the source
distribution.
* tests/test-diff-pkg.cc (in_out_spec): Make this test harness run
on the new test input above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
In the manual of abidiff, explain the kind of changes that flip the
ABIDIFF_ABI_INCOMPATIBLE_CHANGE flag.
* doc/manuals/abidiff.rst: Explain the kind of changes that flip
the ABIDIFF_ABI_INCOMPATIBLE_CHANGE flag.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
The output of several tar file tests for abipkgdiff have the same
name. This is can be a race condition now that these tests are run in
parallel, potentially.
This patch fixes the issue by giving each test output file a different
name.
* tests/test-diff-pkg.cc (in_out_spec): Make the tar format tests
output have different names.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Some children nodes of function_type_diff are traversed in a
non-deterministic order depending on the ordering of elements in an
unordered_map. This can lead to spurious reporting differences
between e.g the x86_64 an i686 platforms.
This patch sorts the parameter diff children nodes of
function_type_diff using the parameter index.
* src/abg-comparison.cc
(function_type_diff::priv::{sorted_subtype_changed_parms_,
sorted_changed_parms_by_id_}): Add two data members.
(function_type_diff::ensure_lookup_tables_populated): Sort the
changed parameters here ...
(function_type_diff::report): ... not here.
(function_type_diff::chain_into_hierarchy): Chain the *sorted*
changed parameters.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
package::extracted_packages_parent_dir() is not returning a unique
directory path. So several abipkgdiff processes end up using the same
temporary directory. Ooops.
This patch addresses the issue by making that function use mkdtemp().
The patch also makes the unit tests for abipkgdiff run the instances
of abipkgdiff in parallel so that we test this once and for all.
* tools/abipkgdiff.cc: Update copyright notice.
(package::extracted_packages_parent_dir): Use mkdtemp to generate
the unique root directory under which packages are extracted.
* tests/test-diff-pkg.cc (struct test_task): New type.
(main): Use worker threads to run abipkgdiff in parallel,
depending on the number of CPUs advertised by the underlying
machine.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
It appears that there can be cycles in the path made of ancestors. In
that case, diff_has_ancestors_filtered_out() just loops forever.
Oops.
This patch addresses that issue by making
diff_has_ancestors_filtered_out() detect cycles.
* src/abg-comparison.cc (diff_has_ancestor_filtered_out): Add an
overload that takes an additional map of pointer values. Make the
older overload call the new one.
* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm: New test material.
* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt:
New reference output.
* tests/data/test-diff-pkg/libICE-1.0.9-2.el7.x86_64.rpm: New test material.
* tests/data/test-diff-pkg/libICE-debuginfo-1.0.6-1.el6.x86_64.rpm: New test material.
* tests/data/test-diff-pkg/libICE-debuginfo-1.0.9-2.el7.x86_64.rpm:
New test material.
* tests/data/Makefile.am: Add the new test material to source distribution.
* tests/test-diff-pkg.cc (in_out_specs): Run this test harness
over the new tests material above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
I forgot to add these files as part of my previous commit
* test2-filtered-removed-fns-v{0,1}.o: Add these test input files.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Libabigail considers a removed function (or global variable) as being
an incompatible change, whether it has been suppressed or not.
Likewise, even if all function sub-type changes have been suppressed,
changed virtual offset on functions are still considered incompatible.
Thus, abidiff still returns an exit code that reflects an incompatible
change even if the removed symbol change was suppressed.
The rule should rather be that if incompatible changes have been
suppressed, abidiff (and the other tools) should take that into
account and not return an exit code that reflects incompatible
changes.
This patch implements that rule, at least for the incompatible changes
that are detected so far.
* src/abg-comparison.cc (corpus_diff::has_incompatible_changes):
Consider the *net* number of removed function and variable
symbols. Also, if all function sub-type changes have been
suppressed, then no virtual offset change should be considered
incompatible.
* tests/data/test-abidiff-exit/test1-voffset-change-report1.txt
* tests/data/test-abidiff-exit/test1-voffset-change.abignore
* tests/data/test-abidiff-exit/test2-filtered-removed-fns-report0.txt
* tests/data/test-abidiff-exit/test2-filtered-removed-fns-report1.txt
* tests/data/test-abidiff-exit/test2-filtered-removed-fns-v0.c
* tests/data/test-abidiff-exit/test2-filtered-removed-fns-v1.c
* tests/data/test-abidiff-exit/test2-filtered-removed-fns.abignore
* tests/data/Makefile.am: Add the new test material above to
source distribution.
* tests/test-abidiff-exit.cc (InOutSpec::in_suppr_path): New data
member.
(in_out_specs): Adjust. Add new test inputs.
(main): Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This is from the problem report at
https://sourceware.org/bugzilla/show_bug.cgi?id=19707.
GCC 5.3.1, when invoked with -g -O2 emits some debug info where some
virtual member functions with linkage name have no reference to any
underlying symbol. When that binary is compared to its counterpart
compiled with -g, the member function in question does have an
underlying symbol and thus the comparison of the enclosing types yield
a spurious change report like:
method virtual void unity::scopes::ScopeBase::stop() didn't have any
linkage name, and it now has: '_ZN5unity6scopes9ScopeBase4stopEv'
This patch introduces a pass in the DWARF reader which fixes up
virtual member function with linkage and no underlying symbol. If
there is a symbol with a name equals to the linkage name, the virtual
member function has its underlying symbol set to that symbol.
This fixes the spurious change report.
* src/abg-dwarf-reader.cc (die_function_decl_map_type): New
typedef.
(read_context::die_function_with_no_symbol_map_): New data member.
(read_context::die_function_decl_with_no_symbol_map): New
accessor.
(read_context::fixup_functions_with_no_symbols): New member
function.
(finish_member_function_reading): Take a read_context. Schedule
virtual member functions with linkage and no underlying symbol to
be fixed up after all the debug info is read.
(build_function_decl): After a virtual member function_decl has
been updated, if it has its underlying symbol and was scheduled
for fixup, then de-schedule it.
(build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust
call to finish_member_function_reading.
(read_corpus_from_elf): Move the pure ELF (symbol and other mundane
information) information reading ...
(read_debug_info_into_corpus): ... here. Make it happen *before*
actual reading of DWARF information. We need symbol information
to be present and fully set before we start reading debug info.
This is so that we can know when a virtual member function doesn't
need to be fixed up. Also, perform the fixup after the debug
information was read.
* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* doc/manuals/abidw.rst: Update the manual for the new --verbose
option.
* tools/abidw.cc (options::do_log): New data member.
(options::options): Initialize it.
(display_usage): New string for --verbose.
(parse_command_line): Parse the --verbose option.
(main): Set the the logging option.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Since libabigail now uses pthreads via the abigail::workers namespace,
the libabigail shared library should link with pthreads. Many to
Michi Henning for raising this.
* src/Makefile.am: Add -pthread to libabigail_la_LDFLAGS.
* tools/Makefile.am: Do not use abinilint_LDFLAGS when it should
be abinilint_LDADD. This one was fixed by Michi Henning.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
There are holes in the list of dependencies mentioned in the
document. This patch plugs some of them.
Many thanks to Michi Henning for raising this.
* COMPILING: Mention elfutils, libtool, autoconf, automake and
libtool.
* doc/website/mainpage.txt: Mention automake and libtool. Fix a typo.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
I forgot that functions that have no elf symbol can still make it to
the internal diff representation, so we always need to take that into
account.
* src/abg-comparison.cc
(function_suppression::suppresses_function): Make sure a function
has a symbol before (de)referencing it.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* include/abg-ir.h (var_decl::get_naked_type): Declare new member function.
* src/abg-ir.cc (var_decl::get_naked_type): Define it.
(equals): For the var_decl overload, avoid copying symbol
smart pointers. Likewise for variable type smart pointers.
(hash_type_or_decl): Avoid accessing canonical type smart pointer.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Various style cleanups and comment additions here and there.
* include/abg-ir.h: Add missing comments. Space cleanups. Use
shorter typedefs rather than long template instantiation names.
Use string rather than the longer std::string.
* src/abg-ir.cc: Space cleanups. Add missing comments. User
shorter typedefs.
* src/abg-reader.cc: Likewise.
* src/abg-writer.cc: Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This patch implements string interning optimization. One can read
about the principles of this optimization at
https://en.wikipedia.org/wiki/String_interning.
The patch introduces an abigail::interned_string type, as well as an
abigail::interned_string_pool type. Each environment type owns a
string pool and strings are interned in that pool for all types and
decls of that environments. The interned_string has methods to
interact seemingly with std::string including a hashing function. Of
course hashing and comparing interned_string is faster than for
std::string.
To enable ABI artifacts to intern strings, each constructor of ABI
artifacts now takes the environment it's constructed in as parameter.
From the environment, it can thus use the interned string pool.
The patch then changes declaration names to be of type
interned_string, and performs the necessary adjustments. The hash
maps that hash strings coming from those declaration names are
adjusted to hash interned_string.
* include/Makefile.am: Add the new abg-interned-str.h file to
source distribution.
* include/abg-corpus.h (corpus::corpus): Re-arrange the order of
* src/abg-corpus.cc
(corpus::exported_decls_builder::priv::get_id): Return
interned_string rather than std::string.
(corpus::corpus): Re-arrange the order of parameters: take an
environment as first parameter. parameters: take an environment
as first parameter.
* include/abg-dwarf-reader.h (lookup_symbol_from_elf)
(lookup_public_function_symbol_from_elf): Likewise.
* src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab)
(lookup_symbol_from_gnu_hash_tab)
(lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab)
(lookup_symbol_from_elf, lookup_public_function_symbol_from_elf)
(lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf)
(lookup_public_function_symbol_from_elf): Take an environment as
first parameter and adjust.
(build_translation_unit_and_add_to_ir)
(build_namespace_decl_and_add_to_ir, build_type_decl)
(build_enum_type, finish_member_function_reading)
(build_class_type_and_add_to_ir, build_function_type)
(read_debug_info_into_corpus, read_corpus_from_elf): Adjust.
* include/abg-fwd.h: Include abg-interned-str.h
(get_type_name, get_function_type_name, get_method_type_name):
Return a interned_string, rather than a std::string.
* include/abg-interned-str.h: New declarations for interned strings
and their pool.
* include/abg-ir.h (environment::intern): Declare new method.
(elf_symbol::{g,s}et_environment): Likewise.
(type_or_decl_base::type_or_decl_base): Make the default
constructor private.
({translation, type_or_decl_base}::set_environment)
(set_environment_for_artifact): Take a const environment*.
(elf_symbol::elf_symbol)
(elf_symbol::create)
(type_or_decl_base::type_or_decl_base)
(translation::translation, decl_base::decl_base)
(scope_decl::scope_decl, type_base::type_base)
(type_decl::type_decl, scope_type_decl::scope_type_decl)
(namespace_decl::namespace_decl)
(enum_type_decl::enumerator::enumerator)
(function_type::function_type, method_type::method_type)
(template_decl::template_decl, function_tdecl::function_tdecl)
(class_tdecl::class_tdecl, class_decl::class_decl): Take an
environment.
(type_or_decl_base::operator=)
(enum_type_decl::enumerator::get_environment): Declare new method.
(decl_base::{peek_qualified_name, peek_temporary_qualified_name,
get_qualified_name, get_name, get_qualified_parent_name,
get_linkage_name}, qualified_type_def::get_qualified_name)
(reference_type_def::get_qualified_name)
(array_type_def::get_qualified_name)
(enum_type_decl::enumerator::{get_name, get_qualified_name})
({var,function}_decl::get_id)
(function_decl::parameter::{get_type_name, get_name_id}): Return
an interned_string, rather than a std::string.
(decl_base::{set_qualified_name, set_temporary_qualified_name,
get_qualified_name, set_linkage_name})
(qualified_type_def::get_qualified_name)
(reference_type_def::get_qualified_name)
(array_type_def::get_qualified_name)
(function_decl::parameter::get_qualified_name): Take an
interned_string, rather than a std::string.
(class_decl::member_{class,function}_template::member_{class,function}_template):
Adjust.
* src/abg-ir.cc (environment_setter::env_): Make this be a pointer
to const environment.
(environment_setter::visit_begin): Adjust.
(interned_string_pool::priv): Define new type.
(interned_string_pool::*): Define the method declared in
abg-interned-str. h.
(operator==, operator!=, operator+): Define operator for interned_string and
std::string
(operator<<): Define for interned_string.
(translation_unit::priv::env_): Make this be a pointer to const
environment.
(translation_unit::priv::priv): Take a pointer to const
environment.
(elf_symbol::priv::env_): New data member.
(elf_symbol::priv::priv): Adjust. Make an overoad take an
environment.
(translation_unit::{g,s}et_environment): Adjust.
(interned_string_bool_map_type): New typedef.
(environment::priv::classes_being_compared_): Make this hastable
of string be a hashtable of interned_string.
(environment::priv::string_pool_): New data member.
(environment::{get_void_type_decl,
get_variadic_parameter_type_decl}): Adjust.
(type_or_decl_base::priv::env_): Make this be a pointer to const
environment.
(type_or_decl::base::priv::priv): Adjust.
(type_or_decl_base::set_environment)
(set_environment_for_artifact): Take a pointer to const
environment.
(elf_symbol::{g,s}et_environment, environment::intern)
(type_or_decl_base::operator=): Define new methods.
(decl_base::priv::{name_, qualified_parent_name_,
temporary_qualified_name_, qualified_name_, linkage_name_}): Make
these data member be of tpe interned_string.
(decl_base::priv::priv): Make this take an environment. Adjust.
(decl_base::{peek_qualified_name, peek_temporary_qualified_name,
get_linkage_name, get_qualified_parent_name, get_name,
get_qualified_name}, get_type_name, get_function_type_name)
(get_method_type_name, get_node_name)
(qualified_type_def::get_qualified_name)
(pointer_type_def::get_qualified_name)
(array_type_def::get_qualified_name)
(enum_type_decl::enumerator::get_qualified_name)
(var_decl::get_id, function_decl::get_id)
(function_decl::parameter::get_{name_id, type_name}): Return an
interned_string.
(decl_base::{set_qualified_name, set_temporary_qualified_name})
(qualified_type_def::get_qualified_name)
(pointer_type_def::get_qualified_name)
(reference_type_def::get_qualified_name)
(array_type_def::get_qualified_name)
(function_decl::parameter::get_qualified_name): Take an
interned_string.
(decl_base::{set_name, set_linkage_name}): Intern the std::string
passed in parameter.
(equals): In the overload for decl_base, adjust for a little speed
optimization that is justified by profiling.
(pointer_type_def::priv::{internal_qualified_name_,
temp_internal_qualified_name_}): Make these data member be
interned_string.
(enum_type_decl::enumerator::priv::env_): New data member.
(enum_type_decl::enumerator::priv::{name_, qualified_name}): Make
these data member be of type interned_string.
(enum_type_decl::enumerator::get_environment): New method.
(enum_type_decl::enumerator::priv::priv) Adjust.
(typedef_decl::operator==): Implement a little speed optimization.
(var_decl::priv::nake_type_): New data member.
(var_decl::priv::id_): Make this data member be of type
interned_string.
(equals): In the overload for var_decl, function_type,
function_decl, adjust for the use of interned_string.
(function_decl::priv::id_): Make this be of type interned_string.
(scope_decl::{add_member_decl, insert_member_decl})
(lookup_function_type_in_translation_unit)
(synthesize_type_from_translation_unit, lookup_node_in_scope)
(lookup_type_in_scope, scope_decl::scope_decl)
(qualified_type_def::qualified_type_def)
(qualified_type_def::get_qualified_name)
(pointer_type_def::pointer_type_def)
(reference_type_def::reference_type_def)
(array_type_def::array_type_def, array_type_def::append_subrange)
(array_type_def::get_qualified_name)
(enum_type_decl::enum_type_decl)
(enum_type_decl::enumerator::get_qualified_name)
(enum_type_decl::enumerator::set_name)
(typedef_decl::typedef_decl, var_decl::var_decl)
(function_type::function_type, method_type::method_type)
(function_decl::function_decl)
(function_decl::parameter::parameter)
(class_decl::priv::comparison_started)
(class_decl::add_base_specifier)
(class_decl::base_spec::base_spec)
(class_decl::method_decl::method_decl)
(type_tparameter::type_tparameter)
(non_type_tparameter::non_type_tparameter)
(template_tparameter::template_tparameter)
(type_composition::type_composition)
(function_tdecl::function_tdecl, class_tdecl::class_tdecl)
(qualified_name_setter::do_update): Adjust.
(translation_unit::translation_unit, elf_symbol::elf_symbol)
(elf_symbol::create, type_or_decl_base::type_or_decl_base)
(decl_base::decl_base, type_base::type_base)
(type_decl::type_decl, scope_type_decl::scope_type_decl)
(namespace_decl::namespace_decl)
(enum_type_decl::enumerator::enumerator, class_decl::class_decl)
(template_decl::template_decl, function_tdecl::function_tdecl)
(class_tdecl::class_tdecl): Take an environment.
* src/abg-comparison.cc
(function_suppression::suppresses_function): Adjust.
* src/abg-reader.cc (read_translation_unit)
(read_corpus_from_input, build_namespace_decl, build_elf_symbol)
(build_function_parameter, build_function_decl, build_type_decl)
(build_function_type, build_enum_type_decl, build_enum_type_decl)
(build_class_decl, build_function_tdecl, build_class_tdecl)
(read_corpus_from_native_xml): Likewise.
* src/abg-writer.cc (id_manager::m_cur_id): Make this mutable.
(id_manager::m_env): New data member.
(id_manager::id_manager): Adjust.
(id_manager::get_environment): New method.
(id_manager::{get_id, get_id_with_prefix}): Return an
interned_string.
(type_ptr_map): Make this be a hash map of type_base* ->
interned_string, rather a type_base* -> string.
(write_context::m_env): New data member.
(write_context::m_type_id_map): Make this data member be mutable.
(write_context::m_emitted_type_id_map): Make this be a hash map of
interned_string -> bool, rather than string -> bool.
(write_context::write_context): Take an environment and adjust.
(write_context::get_environment): New method.
(write_context::get_id_manager): New const overload.
(write_context::get_id_for_type): Return an interned_string; adjust.
(write_context::{record_type_id_as_emitted,
record_type_as_referenced}): Adjust.
(write_context::type_id_is_emitted): Take an interned_string.
(write_context::{type_is_emitted,
record_decl_only_type_as_emitted}): Adjust.
(write_translation_unit, write_corpus_to_native_xml, dump):
Adjust.
* tools/abisym.cc (main): Adjust.
* tests/data/test-read-write/test22.xml: Adjust.
* tests/data/test-read-write/test23.xml: Adjust.
* tests/data/test-read-write/test26.xml: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
* src/abg-ir.cc (function_tdecl::traverse): Do not crash when
traversing a template with empty pattern.
(class_tdecl::operator==): Do not crash when comparing templates
with empty patterns.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Some ABI artifact declared in the internal representation don't have
inequality operator (!=) declared. I thought relying on the !=
operator provided by std::rel_ops would be enough, but it's not.
Sometimes, especially for smart pointers to ABI artifacts we do not
want the != operator of shared_ptr to be picked by argument dependent
lookup. Rather, we want the deep operator!= to be picked up. In certain
cases, this was causing subtle spurious change comparison reports.
This patch thus systematically declares (and defines) operator!=
whenever operator== is declared.
* include/abg-ir.h ({translation_unit, elf_symbol::version,
context_rel, decl_base, type_base, type_decl,
array_type_def::subrange_type, enum_type_def::enumerator,
dm_context_rel, template_parameter}::operator!=): Declare.
(operator==): Make the overload form translation_unit_sptr,
scope_decl_sptr, class_decl::base_spec_sptr,
class_decl::member_function_template_sptr,
class_decl::member_class_template_sptr take const references.
(operator!=): Declare an an overload for the non-member operator
!= of translation_unit_sptr, elf_symbol_sptr,
type_or_decl_base_sptr, type_base_sptr, scope_decl_sptr,
type_decl, qualified_type_def_sptr, pointer_type_def_sptr,
reference_type_def_sptr, enum_type_decl_sptr, class_decl_sptr,
class_decl::base_spec_sptr,
class_decl::member_function_template_sptr,
class_decl::member_class_template_sptr.
* src/abg-ir.cc ({translation_unit, elf_symbol::version,
context_rel, decl_base, type_base, type_decl,
array_type_def::subrange_type, enum_type_def::enumerator,
dm_context_rel, template_parameter}::operator!=): Define.
(operator==): Make the overload for translation_unit_sptr,
scope_decl_sptr, class_decl::base_spec_sptr,
class_decl::member_function_template_sptr,
class_decl::member_class_template_sptr take const references.
(operator!=): Define an an overload for the non-member operator !=
of translation_unit_sptr, elf_symbol_sptr, type_or_decl_base_sptr,
type_base_sptr, scope_decl_sptr, type_decl,
qualified_type_def_sptr, pointer_type_def_sptr,
reference_type_def_sptr, enum_type_decl_sptr, class_decl_sptr,
class_decl::base_spec_sptr,
class_decl::member_function_template_sptr,
class_decl::member_class_template_sptr.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
I forgot to add a test reference output file to the source
distribution and this breaks "make distcheck".
Fixed thus.
* tests/data/Makefile.am: Add file
test-diff-suppr/test28-add-aliased-function-report-0.txt to source
distribution.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
When loading two binaries (e.g, when the library is used by abidiff),
and when the second one does have deep types (e.g, classes with
recursively deep hierarchies) with lots of duplicated types in lots of
translation units, canonicalizing the types of the second binaries can
take a *lot* of time, given the quadratic nature of the structural
type comparisons that take place and the cheer number of those type
comparisons (because of the duplication).
There is already an optimization based on the One Definition Rule in
the canonicalization code. That optimization avoids structural
comparison of types of the same corpus which have the same name. But
then, this optimization only works on types of the first corpus.
As soon as we are loading a second corpus, all types being
canonicalized are coming from a corpus that is different from the
first corpus, by definition. So a structural comparison is taking
place for *all* those types.
The patch extends the existing optimization to make it work on the
second corpus being loaded. Once a type from the second corpus is
canonicalized, the canonical type is cached inside the corpus. Then,
later, when a type with the same name has to be canonicalized, the
system looks inside the cache of that corpus to see if there is a
canonicalized type the same name.
I tested the patch on this command:
abipkgdiff --d1 nss-debuginfo-3.19.1-8.el6_7.i686.rpm \
--d2 nss-debuginfo-3.21.0-0.1.el6_7.i686.rpm \
nss-3.19.1-8.el6_7.i686.rpm \
nss-3.21.0-0.1.el6_7.i686.rpm
I whitnessed a x10 speedup, at least.
On binaries that don't have a lot of duplicated deep types, the patch
doesn't have any noticeable effect. At lesat It doesn't slow things
down in that case.
* include/abg-corpus.h (corpus::{record_canonical_type,
lookup_canonical_type}): Declare new member functions.
* src/abg-corpus.cc (corpus::priv::canonical_types_): New data
member.
(corpus::{record_canonical_type, lookup_canonical_type}): Define
new member functions.
* src/abg-ir.cc (type_base::get_canonical_type_for): Cache the
canonical type inside the corpus of the type being canonicalized.
Then later when canonicalizing another type, lookup in the cache
inside its corpus to see if there is a type with the same name.
* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>