Commit Graph

363 Commits

Author SHA1 Message Date
Dodji Seketeli
93fea0667e Better recognize qualified void type
This fixes Bug 20329 - DW_TAG_const_type with no DW_AT_type not recognized as "const void".

It appears that GCC sometimes emits "const void" types by emitting a
const type DIE with no type attribute.  The DWARF reader didn't
recognize that construct as a qualified void type.

This patch teaches the DWARF reader to recognize that construct.

It also appears that "const void" and "void" are equivalent and can be
emitted interchangeably by compilers (Intel and GCC) in their debug
info.  That can lead to spurious ABI change reports saying that a type
"const void" was changed into a "void" type.

This patch transforms an occurrence of "const void" type into a "void"
type in the internal representation when reading DWARF.  This does
away with the spurious change that appears when comparing selected
binaries emitted with the intel against binaries emitted with GCC.

	* include/abg-ir.h (environment::is_void_type): Declare new member
	function.
	* src/abg-ir.cc (environment::is_void_type): Define new member
	function.
	* src/abg-dwarf-reader.cc (maybe_strip_qualification): Strip const
	qualifier from const void.
	* tests/data/test-diff-filter/test34-libjemalloc.so.2-gcc-6.1.0:
	New test input.
	* tests/data/test-diff-filter/test34-libjemalloc.so.2-intel-16.0.3: Likewise.
	* tests/data/test-diff-filter/test34-report-0.txt: New reference output.
	* tests/data/Makefile.am: Add the new files above to the source
	distribution.
	* tests/test-diff-filter.cc (in_out_specs): Compare the two new
	binaries above.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Adjust.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Adjust.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt: Adjust.
	* tests/data/test-read-dwarf/test1.abi: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Adjust.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-07-07 14:04:10 +02:00
Dodji Seketeli
10ce99e428 Bug 20194 - Fail to recognize void type represented by DW_TAG_base_type
This patch makes the DWARF reader recognize a "void" type expressed as
a DW_TAG_base_type of size zero and named "void".

	* src/abg-dwarf-reader.cc (build_type_decl): Recognize a
	DW_TAG_base_type of size zero and of name "void" as a void
	type.
	* tests/data/test-diff-filter/test33-libelf.so.0.8.13-gcc: New
	binary test input.
	* tests/data/test-diff-filter/test33-libelf.so.0.8.13-intel16.0.3: Likewise.
	* tests/data/test-diff-filter/test33-report-0.txt: New reference output.
	* tests/data/Makefile.am: Add the new files above to source
	distribution.
	* tests/test-diff-filter.cc (in_out_specs): Make this test harness
	run over the new test inputs above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-07-05 12:52:52 +02:00
Dodji Seketeli
4a751787b0 Fix python interpreter path for el6
On el6, the python interpreter is not found at /bin/python, so let's
use /usr/bin/python in tests/runtestdefaultsupprs.py.in.

	* tests/runtestdefaultsupprs.py.in: Use the python interpreter at
	/usr/bin/python, not the one at /bin/python.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-06-28 09:12:40 +02:00
Chenxiong Qi
95b12167fa Fix package NVR comparison in fedabipkgdiff
When sorting two packages by their {Name Value Release} triplet to
select the latest one, just doing a string comparison of the NVRs is
wrong.  Take for example the packages foo-0.10-1.fc25 and
foo-0.2-1.fc25.  A basic string comparison will result in the string
"foo-0.10-1.fc25" being less than "foo-0.2-1.fc25", and thus
foo-0.2-1.fc25 will be selected as the latest package.  And that is
wrong, because the latest one is obviously foo-0.10-1.fc25.

So, after some research on this, I figured rpm.labelCompare is a
better choice to appropriately compare two NVRs.

Another reason why I chose rpm.labelCompare is because the latest
build in fedabipkgdiff means a build with the latest version.release
within a specific Fedora distribution such as fc23 or fc25.

	* configure.ac: Add new dependency.
	* tests/runtestfedabipkgdiff.py.in (builds): Add new builds for
	running tests to test selecting latest build from a package.
	(packages): Add new package gnutls.
	(GetPackageLatestBuildTest.{test_get_latest_one,
	test_cannot_find_a_latest_build_with_invalid_distro}): Use new
	builds of package gnutls to run tests.
	* tools/fedabipkgdiff (cmp_nvr): New function used to compare nvrs
	by Python built-in function sorted.
	(Brew.listBuilds): Use the new cmp_nvr function.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-06-11 09:10:10 +02:00
Chenxiong Qi
69d2dcd163 Bug 20135 - Make fedabipkgdiff compare ABIs using devel packages
This patch makes fedabipkgdiff compare the ABI of two packages by
taking into account their associated devel packages, along with their
debug info packages.  Taking devel packages into account makes the
tool report changes about types that are defined in public header
files only.  This helps decrease the amount of change reports about
types not defined in public headers.

This is now the default behaviour.

However, if the user provides the new --no-devel-pkg command line
option, then the devel package is not taken into account during the
ABI comparison.

	* doc/manuals/fedabipkgdiff.rst: Add documentation for the new
	--no-devel-pkg command line option, as well as for the new default
	behaviour of taking devel packages into account during ABI
	comparison.
	* tools/fedabipkgdiff (PkgInfo): Add new attribute
	devel_package.
	(RPM.is_devel): New property to determine if rpm is a
	development package.
	(LocalRPM._find_rpm): New method to find a specific rpm.
	(LocalRPM.find_debuginfo): Use new method _find_rpm to find
	debuginfo package.
	(LocalRPM.find_devel): New method to find an associated
	development package.
	(Brew.select_rpms_from_a_build): RPMs selector method is
	changed to select development package also.
	(abipkgdiff): Construct and run abipkgdiff with and without
	--devel-pkg[12] options.
	(magic_construct): Construct PkgInfo with development package.
	(run_abipkgdiff): Run abipkgdiff against rpms with development
	packages.
	(diff_local_rpm_with_latest_rpm_from_koji): Find development
	package, and call method abipkgdiff with development package.
	(build_commandline_args_parser): add new option --no-devel-pkg.
	* tests/runtestfedabipkgdiff.py.in (packages): Add new package
	nss-util.
	(builds): Add new builds of nss-utils, nss-util-3.12.6-1.fc14
	and nss-util-3.24.0-2.0.fc25.
	(rpms): Add new associated rpms of the two new builds.
	(AssertionHelper.assert_functions_changes_summary): New method
	to match and assert functions changes summary.
	(AssertionHelper.assert_abi_comparison_result): Changed to
	support to help assert functions changes summary.
	(MockGlobalConfig.{no_devel_pkg, check_all_subpackages}): New
	fake options with default value for running tests.
	(RPMTest.setUp): add new development package for running test
	case.
	(RPMTest.test_is_devel): New test to test is_devel property.
	(RunAbipkgdiffTest.setUp): Add new development packages for
	running test case.
	(RunAbipkgdiffTest.{test_all_success, test_all_failure,
	test_partial_failure}): Mock global config.
	(RunAbipkgdiffWithDSOOnlyOptionTest): Removed.
	(CompareABIFromCommandLineTest.test_compare_with_no_devel_pkg):
	New test to test fedabipkgdiff with or without --no-devel-pkg
	option.
	* tests/data/Makefile.am: Add new rpms.
	* tests/data/test-fedabipkgdiff/packages/nss-util/3.12.6/1.fc14/
	x86_64/nss-util-3.12.6-1.fc14.x86_64.rpm: New rpm for running
	tests.
	* tests/data/test-fedabipkgdiff/packages/nss-util/3.12.6/1.fc14/
	x86_64/nss-util-debuginfo-3.12.6-1.fc14.x86_64.rpm: New rpm for
	running tests.
	* tests/data/test-fedabipkgdiff/packages/nss-util/3.12.6/1.fc14/
	x86_64/nss-util-devel-3.12.6-1.fc14.x86_64.rpm: New rpm for
	running tests.
	* tests/data/test-fedabipkgdiff/packages/nss-util/3.24.0/2.0.fc25/
	x86_64/nss-util-3.24.0-2.0.fc25.x86_64.rpm: New rpm for running
	tests.
	* tests/data/test-fedabipkgdiff/packages/nss-util/3.24.0/2.0.fc25/
	x86_64/nss-util-debuginfo-3.24.0-2.0.fc25.x86_64.rpm: New rpm
	for running tests.
	* tests/data/test-fedabipkgdiff/packages/nss-util/3.24.0/2.0.fc25/
	x86_64/nss-util-devel-3.24.0-2.0.fc25.x86_64.rpm: New rpm for
	running tests.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-06-09 11:11:33 +02:00
Chenxiong Qi
70614e18f1 Add integration tests for fedabipkgdiff
A new test case class is introduced as integration tests, that is able to
test fedabipkgdiff ability against supported use cases and with other
command line options. Currently, integration tests only aim to ensure
whether expected comparison against rpms and binaries really happen.

	* configure.ac: do not detect shutil module.
	* tests/runtestfedabipkgdiff.py.in: do not import shutil
	anymore.
	(BUILT_ABIPKGDIFF): new global variable to reference the
	abipkgdiff built from source code, as the new test case' tests
	require this command directly rather than mocking the
	global_config.
	(test_data_dir): convert variable name to uppercase,
	reference to the test data directory by absolute path instead of
	relative path.
	(TEST_TOPDIR): new global variable to use data directory as the
	topdir passed to fedabpkgdiff to download rpms.
	(TEST_DOWNLOAD_CACHE_DIR): new global variable referencing a
	fake download cache directory for tests only.
	(packages, builds, rpms): new global variables as a fake
	storage holding packages, builds and rpms.
	(AssertionHelper): new class helping to assert abipkgdiff
	result easily.
	(MockClientSession): new class to mock koji.ClientSession.
	(MockGlobalConfig.abipkgdiff): set this option to global
	variable BUILT_ABIPKGDIFF.
	(MockKojiClientSessin): removed.
	(mock_get_session): removed.
	(GetPackageLatestBuildTest.{test_get_latest_one,
	test_cannot_find_a_latest_build_with_invalid_distro,
	test_cannot_find_a_latest_build_with_invalid_distro}): mock
	koji.ClientSession with new class MockClientSession. Remove
	invalid documentation from docstring. Use new package rather
	than httpd.
	(DownloadRPMTest.setUp): remove self.download_dir and use global
	TEST_DOWNLOAD_CACHE_DIR.
	(DownloadRPMTest.tearDown): do not remove download cache
	directory.
	(DownloadRPMTest.make_remote_file_url): do not omit positional
	argument specifiers in string format.
	(DownloadRPMTest.{test_succeed_to_download_a_rpm,
	test_failed_to_download_a_rpm}): set fake download cache
	directory to mocked get_download_dir in mock.patch decorator.
	(BrewListRPMsTest.test_select_specific_rpms): use new
	MockClientSession to mock koji.ClientSession. Rewrite test by
	using the new package listed in global variable packages.
	(RunAbipkgdiffWithDSOOnlyOptionTest.{test_abipkgdiff_with_dso_only,
	test_abipkgdiff_without_dso_only}): set fake download cache
	directory to mocked get_download_dir in mock.patch decorator.
	(CompareABIFromCommandLineTest): new integration test case.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.100.2/2.fc20/
	i686/dbus-glib-0.100.2-2.fc20.i686.rpm: new rpm for running tests.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.100.2/2.fc20/
	i686/dbus-glib-debuginfo-0.100.2-2.fc20.i686.rpm: new rpm for
	running tests.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.100.2/2.fc20/
	i686/dbus-glib-devel-0.100.2-2.fc20.i686.rpm: new rpm for
	running tests.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.100.2/2.fc20/
	x86_64/dbus-glib-0.100.2-2.fc20.x86_64.rpm: new rpm for running
	tests.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.100.2/2.fc20/
	x86_64/dbus-glib-debuginfo-0.100.2-2.fc20.x86_64.rpm: new rpm
	for running tests.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.100.2/2.fc20/
	x86_64/dbus-glib-devel-0.100.2-2.fc20.x86_64.rpm: new rpm for
	running tests.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.106/1.fc23/
	i686/dbus-glib-0.106-1.fc23.i686.rpm: new rpm for running tests.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.106/1.fc23/
	i686/dbus-glib-debuginfo-0.106-1.fc23.i686.rpm: new rpm for
	running tests.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.106/1.fc23/
	i686/dbus-glib-devel-0.106-1.fc23.i686.rpm: new rpm for running
	tests.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.106/1.fc23/
	x86_64/dbus-glib-0.106-1.fc23.x86_64.rpm: new rpm for running
	tests.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.106/1.fc23/
	x86_64/dbus-glib-debuginfo-0.106-1.fc23.x86_64.rpm: new rpm for
	running tests.
	* tests/data/test-fedabipkgdiff/packages/dbus-glib/0.106/1.fc23/
	x86_64/dbus-glib-devel-0.106-1.fc23.x86_64.rpm: new rpm for
	running tests.
	* tests/data/Makefile.am: add new rpms.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-06-01 11:41:55 +02:00
Dodji Seketeli
3e47efb112 Escape all characters when reading a string in ini files
It turns out that when parsing foo = bar\[a-z\], the '[' and ']'
characters where not being escaped while parsing the string
"bar\[a-z\]".

This patch fixes that.

	* src/abg-ini.cc (read_context::peek): Take an output parameter to
	tell the caller when this function escaped the returned
	character.  Added an overload without this new parameter.
	(read_context::read_string): Accept all characters as part of the
	string.
	* tests/data/test-diff-suppr/test7-var-suppr-9.suppr: New test
	input.
	* tests/data/test-diff-suppr/test7-var-suppr-report-9.txt: New
	test reference output.
	* tests/data/Makefile.am: Add the files above to source
	distribution.
	* tests/test-diff-suppr.cc (in_out_spec): Run a new comparison of
	libtest7-var-suppr-v{0,1}.so this time using the new
	test7-var-suppr-9.suppr specification that exercices a string with
	the escaped characters that we were having difficulty with.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-31 12:37:57 +02:00
Dodji Seketeli
b36ca1501e Bug 20180 - Support system-wide suppression specifications
This patch adds support for loading system and user level suppression
specifications for libabigail tools.

At launch time, relevant libabigail tools (abidiff, abipkgdiff
fedabipkgdiff for now) read the default system suppression
specification file, if it's present, from a file which path is the
value of the environment variable
LIBABIGAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE, if set, or from the file
$libdir/libabigail/default.abignore.

Then it reads the user system suppression specification file, if it's
present, from a file which path is the value of the environment
variable LIBABIGAIL_DEFAULT_USER_SUPPRESSION_FILE, if set, or from the
file $HOME/.abignore.

The content of the user system suppression file is merged with the
content of default system suppression file.

That content is also merged with the content of the suppression
specification files that might be provided by the --suppressions
command line option of the invoked tools.

The resulting set of all these suppression specifications is thus used
to filter the ABI change reports that are emitted.

abidiff, abipkgdiff and abipkgdiff gain a --no-default-suppression
option to avoid loading any of these default suppression specification
files.

The patch also installs a default.abignore file into $(pkglibdir).
Note that on x86_64, that directory is /usr/lib64/libabigail.  Now we
just need to think about the content of that default.abignore file.

	* doc/manuals/abidiff.rst: Document the default suppression
	scheme, its interaction with the --supprs option and the new
	--no-default option.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* doc/manuals/fedabipkgdiff.rst: Likewise.
	* configure.ac: Generate the tests/runtestdefaultsupprs.py file
	from the new tests/runtestdefaultsupprs.py.in template.
	* default.abignore: New file.
	* Makefile.am: Add it to source distribution.
	* src/Makefile.am: Define the ABIGAIL_ROOT_SYSTEM_LIBDIR
	preprocessor macro that is set the value of the $libdir autotools
	macro.
	* include/abg-tools-utils.h: Update copyright years.
	(get_system_libdir, get_default_system_suppression_file_path)
	(get_default_user_suppression_file_path)
	(load_default_system_suppressions)
	(load_default_user_suppressions): Declare new functions
	* src/abg-tools-utils.cc (get_system_libdir)
	(get_default_system_suppression_file_path)
	(get_default_user_suppression_file_path)
	(load_default_system_suppressions)
	(load_default_user_suppressions): Define new functions.
	(is_regular_file): Amend this so that it return true for symlinks
	to regular files too.
	(is_dir): Amend this so that it returns true for symlinks to
	directories too.
	* tools/abidiff.cc (options::no_default_supprs): New data member.
	(options::options): Initialize the new data member.
	(display_usage): Display a new help string for the new
	--no-default-suppression command line option.
	(parse_command_line): Parse this new command line option.
	(set_diff_context_from_opts): Load the default suppression
	specifications, unless --no-default-suppression or --supprs was
	provided.
	* tools/abipkgdiff.cc (options::no_default_supprs): New data
	member.
	(options::options): Initialize the new data member.
	(parse_command_line): Parse the new --no-default-suppression
	command line option.
	(main): Load the default suppression specifications, unless
	--no-default-suppression or --supprs was provided.
	* tools/fedabipkgdiff (abipkgdiff): Add --no-default-suppression
	to the invocation of abipkgdiff if it was provided on the command
	line.
	(build_commandline_args_parser): Parse the new
	--no-default-suppression command line option.
	* tests/runtestdefaultsupprs.py.in: New test harness template.
	* tests/Makefile.am: Add the new runtestdefaultsupprs.py to the
	set of tests.
	* tests/data/test-default-supprs/test0-type-suppr-0.suppr: New
	test input.
	* tests/data/test-default-supprs/test0-type-suppr-report-0.txt: Likewise.
	* tests/data/test-default-supprs/test0-type-suppr-v0.o: Likewise.
	* tests/data/test-default-supprs/test0-type-suppr-v1.o: Likewise.
	* tests/data/test-default-supprs/dirpkg-1-dir-report-0.txt:
	Likewise.
	* tests/data/test-default-supprs/dirpkg-1-dir1: Likewise.
	* tests/data/test-default-supprs/dirpkg-1-dir2: Likewise.
	* tests/data/Makefile.am: Add new the new tests input above to
	Makefile.am.
	* tests/runtestcanonicalizetypes.sh.in: Pass
	--no-default-suppression to abidiff invocations.
	* tests/runtestdefaultsupprs.py.in: Likewise.
	* tests/test-abidiff-exit.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tools/abidiff.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-30 18:39:49 +02:00
Dodji Seketeli
af3e2fd570 Add --abipkgdiff option to fedabipkgdiff
When running the 'fedabipkgdiff' tool that is in the build directory,
before "make install", we want to use the 'abipkgdiff' command line
tool that is in the build directory, not the one that might be
at $PATH/bin/abipkgdiff.

To do so, this patch adds a --abipkgdiff <path/to/a/given/abipkgdiff>
option so that the user can chose where to find the 'abipkgdiff'
binary to use.

Note that there is no regression test for this option yet because for
that, we'd this bug to be fixed first:
https://sourceware.org/bugzilla/show_bug.cgi?id=20147.

	* tools/fedabipkgdiff (build_path_to_abipkgdiff): Define new
	function.
	(abipkgdiff): Invoke the new build_path_to_abipkgdiff() here.
	(build_commandline_args_parser): Parse the new --abipkgdiff
	option.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-30 16:24:53 +02:00
Dodji Seketeli
7013500ca7 Add test data for tests/runtestfedabipkgdiff.py
While applying the patch 59917a8 and resolving the conflicts that
arose then, I forgot to git add the RPMs that were needed by the
accompanying test.

This test fixes that.

	* tests/data/test-fedabipkgdiff/dbus-glib-0.104-3.fc23.x86_64.rpm:
	New file.
	* tests/data/test-fedabipkgdiff/dbus-glib-0.80-3.fc12.x86_64.rpm: Likewise.
	* tests/data/test-fedabipkgdiff/dbus-glib-debuginfo-0.104-3.fc23.x86_64.rpm:
	Likewise.
	* tests/data/test-fedabipkgdiff/dbus-glib-debuginfo-0.80-3.fc12.x86_64.rpm:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-25 12:29:28 +02:00
Chenxiong Qi
59917a8118 Bug 20085 - Add --dso-only option to fedabipkgdiff
abipkgdiff supports --dso-only to compare only ABI of shared libraries
instead of all binaries. So, with adding this option to fedabipkgdiff,
its user is also able to let fedabipkgdiff compare ABI of shared
libraries, or not.

	* tools/fedabipkgdiff: Do not import shlex anymore.
	(ABIDIFF_OK, ABIDIFF_ERROR, ABIDIFF_USAGE_ERROR)
	(ABIDIFF_ABI_CHANGE): New global constant variables.
	(abipkgdiff): Pass the --dso-only option to the abipkgdiff command
	line tool, if that option was passed to fedabipkgdiff. Build this
	abipkgdiff command invocation from an array of strings, rather
	than from formatting a string.  This makes us get rid of the shlex
	module.  Fix typo in dry-run logged string.  If there was an
	internal error reported by abipkgdiff, report it to stderr.
	(build_commandline_args_parser): Parse the --dso-only command line
	option.
	* tests/runtestfedabipkgdiff.py.in (fedabipkgdiff_mod): Fix a typo
	in initializing this global variable.
	(test_data_dir): New global variable, that is used to reference
	tests/data/test-fedabipkgdiff/.
	(RunAbipkgdiffTest.{test_all_success, test_partial_failure}): Fix
	typo.
	(Mockglobalconfig.{koji_topdir, dso_only}): New data members.
	(GetPackageLatestBuildTest.{test_get_latest_one,
	test_cannot_find_a_latest_build_with_invalid_distro,
	test_succeed_to_download_a_rpm, test_failed_to_download_a_rpm}):
	Fix typo.
	(BrewListRPMsTest.test_select_specific_rpms): Fix typo.
	(RunAbipkgdiffWithDSOOnlyOptionTest): New test case class.
	* doc/manuals/fedabipkgdiff.rst: update document for this new
	--dso-only option.
	* tests/data/test-fedabipkgdiff/dbus-glib-0.104-3.fc23.x86_64.rpm:
	New symbolic link to
	test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64.rpm.
	* tests/data/test-fedabipkgdiff/dbus-glib-0.80-3.fc12.x86_64.rpm:
	New symbolic link to
	test-diff-pkg/dbus-glib-0.80-3.fc12.x86_64.rpm.
	* tests/data/test-fedabipkgdiff/dbus-glib-debuginfo-0.104-3.fc23.x86_64.rpm:
	New symbolic link to
	test-diff-pkg/dbus-glib-debuginfo-0.104-3.fc23.x86_64.rpm.
	* tests/data/test-fedabipkgdiff/dbus-glib-debuginfo-0.80-3.fc12.x86_64.rpm:
	New symbolic link to
	test-diff-pkg/dbus-glib-debuginfo-0.80-3.fc12.x86_64.rpm.
	* tests/data/Makefile.am: add tests/data/test-fedabipkgdiff so
	that this data directory and all things within it can be included
	in tarball.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-25 09:42:21 +02:00
Dodji Seketeli
e19bf5627a Make abi{pkg}diff filter out changes about private types
This is to address the following enhancement requests:

    #19588 - Add a --headers-dir1 and --headers-dir2 option to abidiff
    #19948 - Add --devel-pkg1 and --devel-pkg2 options to abipkgdiff

When the user specifies where to find header files for two binaries
(or packages) being compared, this patch generates a type suppression
specification that filters out change reports about types that are
defined in files that are not in the set of header files specified.

The type suppression specification also suppresses change reports
about changed/added/removed virtual member functions which enclosing
class type matches the type suppression specification.

There is a corner case that the patch handles too, and that is
exhibited by the accompanying test case for abidiff.  There can be a
class defined by DWARF as having no source location and as being a
pure declaration.  This can be a class declaration that has inline
virtual members only, and one or several non-defined virtual methods
too.  When that declaration is included in a source file, GCC
generates debug info that describes that class as being a
declaration-only class with no source declaration.  This patch
considers such a class as being non defined; you know, like a true
opaque type.  So it's considered being not defined in any public
header file.  Changes to this kind of class are thus filtered out.

	* include/abg-comp-filter.h: Update copyright year.
	* src/abg-comp-filter.cc (has_virtual_mem_fn_change): Make this
	static function become exported.
	(has_virtual_mem_fn_change): Declare new function.
	* include/abg-suppression.h
	(suppression_base::{get,set}_is_artificial): Declare new
	accessors.
	(type_suppression::get_source_locations_to_keep): Return an
	unordered set of strings, not a vector.  Add a non-const overload.
	(type_suppression::set_source_locations_to_keep): Set an unordered
	set of strings, not a vector.
	* src/abg-suppression.cc (suppression_base::priv::is_artificial_):
	New data member.
	(suppression_base::priv::priv): Initialize the new data member.
	(suppression_base::{get,set}_is_artificial): Define new accessors.
	(type_suppression::priv::source_locations_to_keep_): Change the
	vector of strings representing source file names into unordered
	set of string.
	(type_suppression::get_source_locations_to_keep): Return an
	unordered set of strings, not a vector.  Define a non-const
	overload.
	(type_suppression::set_source_locations_to_keep): Set an unordered
	set of strings, not a vector.
	(type_suppression::suppresses_diff): Make this suppress virtual
	member function diffs if the enclosing type of the changed virtual
	member is suppressed by the current type_suppression.
	(read_type_suppression): Adjust to use the fact that the source
	locations are not stored in an unordered set, not in a vector
	anymore.  Otherwise, using a vector here make things too slow.
	(type_suppression::suppresses_type): Likewise.  Also, If the type
	we are looking at has no location because it's a true opaque type
	and if the current suppression is an artificial suppression that
	is meant to suppress change reports about non-public types, then
	suppress the type.
	* include/abg-tools-utils.h (gen_suppr_spec_from_headers): Declare
	new public function.
	* src/abg-tools-utils.cc (PRIVATE_TYPES_SUPPR_SPEC_NAME): Define a
	new constant variable.
	(handle_fts_entry): Define new static function.
	(gen_suppr_spec_from_headers): Define new public function.
	* src/abg-comparison.cc
	(corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars):
	If a type suppression suppresses a given class C, make it change
	added/removed virtual functions whose enclosing type is C.
	* tools/abidiff.cc (options::{headers_dir1, headers_dir2}): New
	data members.
	(display_usage): Add help strings for --headers-dir1 and
	--headers-dir2.
	(parse_command_line): Parse the new --headers-dir1 and
	--headers-dir2 options.
	(set_diff_context_from_opts): Generate suppression specifications
	to filter out changes on private types, if --headers-dir1 or
	--headers-dir2 is given.
	* tools/abipkgdiff.cc (options::{devel_package1, devel_package2}):
	New data members.
	(typedef package_sptr): New typedef.
	(enum package::kind): New enum.
	(package::kind_): New data member.  This replaces ...
	(package::is_debug_info_): ... this data member.
	(package::{devel_package_, private_types_suppressions_}): New data
	members.
	(package::package): Adjust.
	(package::get_kind): Define new member function.  This replaces
	...
	(package::is_debug_info): ... this member function overload.
	(package::set_kind): Define new member functin.  It replaces ...
	(package::is_debug_info): ... this member function overload.
	(package::{devel_package, private_types_suppressions}): Define new
	accessors.
	(package::erase_extraction_directies): Erase the sub-directory
	where development packages are extracted to.
	(compare_args::private_types_suppr{1,2}): New data members.
	(compare_args::compare_args): Adjust.
	(display_usage): Add help strings for --devel-pkg1/--devel-pkg2.
	(compare): Make the overload that compares elf files take private
	types suppressions.  Add the private types suppressions to the
	diff context.
	(pthread_routine_compare): Adjust the call to compare.
	(maybe_create_private_types_suppressions): Define new static
	function.
	(pthread_routine_extract_pkg_and_map_its_content): If a devel
	package was specified for the main package then extract it in
	parallel with the other package extraction.  When the extraction
	is done, create private types suppressions by visiting the
	directories that contain the header files.
	(compare): In the overload that compares packages by scheduling
	comparison of individual elf files that are in the packages, pass
	in the private type suppressions too.
	(parse_command_line): Parse the new --devel-pkg{1,2} command line
	options.
	(main): Associate the devel package to the main package, if the
	--devel-pkg{1,2}.
	* doc/manuals/abidiff.rst: Add documentation about the new
	--headers-dir1 and --headers-dir2 options.
	* doc/manuals/abipkgdiff.rst: Likewise, add documentation about
	the new --devel-pkg1 and --devel-pkg2 libraries.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt:
	New test reference output.
	* tests/data/test-diff-pkg/tbb-devel-4.1-9.20130314.fc22.x86_64.rpm:
	New test input package.
	* tests/data/test-diff-pkg/tbb-devel-4.3-3.20141204.fc23.x86_64.rpm: Likewise.
	* tests/test-diff-pkg.cc b/tests/test-diff-pkg.cc
	(InOutSpec::{first,second}_in_devel_package_path): New data
	members.
	(in_out_specs): Adjust.  Also, add a new entry describing the new
	test inputs above.
	(test_task::perform): When the new test entry contains devel
	packages, pass them to abipkgdiff using the --devel1 and --devel2
	options.
	* tests/data/test-diff-suppr/test30-include-dir-v0/test30-pub-lib-v0.h:
	A new test input source code.
	* tests/data/test-diff-suppr/test30-include-dir-v1/test30-pub-lib-v1.h: Likewise.
	* tests/data/test-diff-suppr/test30-priv-lib-v0.cc: Likewise.
	* tests/data/test-diff-suppr/test30-priv-lib-v0.h: Likewise.
	* tests/data/test-diff-suppr/test30-priv-lib-v1.cc: Likewise.
	* tests/data/test-diff-suppr/test30-priv-lib-v1.h: Likewise.
	* tests/data/test-diff-suppr/test30-pub-lib-v0.cc: Likewise.
	* tests/data/test-diff-suppr/test30-pub-lib-v0.so: Add new test
	binary input.
	* tests/data/test-diff-suppr/test30-pub-lib-v1.cc: Add new test
	input source code.
	* tests/data/test-diff-suppr/test30-pub-lib-v1.so: Add new test
	binary input.
	* tests/data/test-diff-suppr/test30-report-0.txt: Add new test
	reference output.
	* tests/data/test-diff-suppr/test30-report-1.txt: Add new test
	reference output.
	* tests/test-diff-suppr.cc (InOutSpec::headers_dir{1,2}): New data
	members.
	(InOutSpec::abidiff_options): Renamed the bidiff_options data
	member into this.
	(in_out_specs): Adjust.  Also, added the new test input above to
	this.
	(main): Adjust to invoke abidiff with the new --hd1 and --hd2
	options if the input specs for the tests has the new
	InOutSpec::headers_dir{1,2} data member set.  Renamed bidiff into
	abidiff.
	* tests/data/Makefile.am: Add the new test inputs to the source
	distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-24 10:32:08 +02:00
Dodji Seketeli
b28cb4ec6d Fix whitespaces in autotools files
* configure.ac: Fix some white spaces.
	* tests/Makefile.am: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-22 23:20:13 +02:00
Dodji Seketeli
1fc1032e7d Fix invocation of delete operator in test-read-dwarf.cc
* tests/test-read-dwarf.cc (main): Call delete[], not delete.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-22 23:20:13 +02:00
Dodji Seketeli
ce5e4889b1 Plug leak of debug info handles
On recent elfutils where the libdw's function dwarf_getalt exists, we
don't need to try and find the alternate debug info file ourselves by
using the function dwfl_standard_find_debuginfo.  Furthermore, when we
use that function on those recent elfutils versions, we leak the elf
resources allocated in the debug info resources; we also leak the file
descriptor to access the alternate debug info sections.

More generally, we also leak debug info handles used to access debug
info when using get_soname_of_elf_file and get_type_of_elf_file.

This patch plugs those leaks.

In the first case, if the function dwarf_getalt exists, the patch just
uses it to get the alternate debug info.  Otherwise, the patch uses
the dwfl_standard_find_debuginfo function like we used to, but then it
tries hard to free the file descriptor and debuginfo memory of the
alternate debug info.

	* configure.ac: Check the presence of dwarf_getalt in libdw.  If
	it's present, define the preprocessor macro
	LIBDW_HAS_DWARF_GETALT.  Update the autoconf configuration
	summary.
	* src/abg-dwarf-reader.cc: Add config.h.
	(find_alt_debug_info_location): Factorize this out of ...
	(find_alt_debug_info): ... this function.  Use dwarf_getalt if
	present, otherwise, keep using dwfl_standard_find_debuginfo.  In
	the later case, return the file descriptor opened to access the
	alternate debug info, by parameter, so that the caller can fclose
	it.
	(read_context::alt_fd_): New data member.
	(read_context::read_context): Initialize the new alt_fd_ data
	member.
	(read_context::load_debug_info): Store the file descriptor used to
	access the alternate debug info into the new alt_fd_ data member.
	(read_context::~read_context): New desctructor.
	(get_soname_of_elf_file, get_type_of_elf_file): Free the elf
	handle.
	(read_context::load_debug_info): Be paranoid in making sure we
	never override alt_dwarf_.
	* tests/data/test-alt-dwarf-file/test0-report.txt: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-22 23:20:13 +02:00
Dodji Seketeli
3dbe842159 Support running "make check-valgrind"
This patch allows maintainers to run:

     make -C <builddir>/tests check-valgrind

This runs the test suite under the Valgrind memory checker.

It also adds this target:

   make -C <builddir>/tests check-valgrind-memcheck-recursive

It runs the memcheck tool on the tests so that programs forked by them
are memchecked too.  This is to allow to memcheck the libabigail tools
that are forked by the individual tests.

	* autoconf-archive/ax_valgrind_check.m4: Add new file.  Copied it
	from http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html.
	* configure.ac: Include the new ax_valgrind_check.m4 file.
	Initialize the valgrind checking on tests.  Update the configure
	status.
	* tests/test-valgrind-suppressions.supp: New valgrind suppression
	file to silence memcheck leak errors from python.
	* tests/Makefile.am: Add test-valgrind-suppressions.supp to source
	distribution.  Add check-valgrind-memcheck-recursive target.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-22 23:20:12 +02:00
Dodji Seketeli
20ffce5239 Do not run fedabipkgdiff tests if --enable-fedabipkgdiff is turned off
* tests/Makefile.am: Make running runtestfedabipkgdiff be
	dependent on ENABLE_FEDABIPKGDIFF.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-16 13:12:05 +02:00
Chenxiong Qi
57dcfb18f5 Bug 19428 - New fedabipkgdiff utility
fedabipkgdiff is a convenient way to compare the ABI of Fedora
packages easily.

The first version of fedabipkgdiff introduced by this patch lets users
perform operations like:

    fedabipkgdiff --from fc23 foo-0.1-1.fc23.x86_64.rpm
    fedabipkgdiff --from fc23 --to fc24 foo
    fedabipkgdiff foo-0.1-1.fc23 foo-0.1-1.fc24
    fedabipkgdiff foo-0.1-1.fc23.i686 foo-0.1-1.fc24.i686
    fedabipkgdiff --all-subpackages foo-0.1-1.fc23 foo-0.1-1.fc24

	* autoconf-archive/ax_compare_version.m4: New file copied from the
	autoconf-archive project.
	* autoconf-archive/ax_prog_python_version.m4: Likewise.
	* autoconf-archive/ax_python_module.m4: Likewise.
	* Makefile.am: Add the new files above to the source distribution.
	* configure.ac: Include the new m4 macros from the autoconf
	archive. Add a new --enable-fedabipkgdiff option. Update the
	report at the end of the configure process to show the status of
	the fedabipkgdiff feature. Add check for prerequisite python
	modules argparse, glob, logging, os, re, shlex, subprocess, sys,
	itertools, urlparse, itertools, shutil, unittest, xdg, koji and
	mock.  These are necessary for the unit test of
	fedabipkgdiff. Generate tests/runtestfedabipkgdiff.py into the
	build directory, from the tests/runtestfedabipkgdiff.py.in input
	file.
	* tools/Makefile.am: Include the fedabipkgdiff to the source
	distribution and install it if the "fedabipkgdiff" feature is
	enabled.
	* tests/Makefile.am: Rename runtestfedabipkgdiff.sh into
	runtestfedabipkgdiff.py.  Add the new runtestfedabipkgdiff.py.in
	autoconf template file in here.
	* tests/runtestfedabipkgdiff.py.in: New unit test file.
	* tools/fedabipkgdiff: New fedabipkgdiff tool.
	* doc/manuals/fedabipkgdiff.rst: New manual.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-13 00:42:36 +02:00
Dodji Seketeli
080b88c9a1 Implement a [suppress_file] suppression directive
abidiff, abipkgdiff and abicompat now recognize a [suppress_file]
directive in suppression specifications.  That directive instructs the
tool to avoid loading some binaries altogether.

This is the first directive that won't act on the result of the
comparison of two binaries.  It actually acts earlier and prevents the
tool from loading some binaries altogether.

The directive looks like:

    [suppress_file]
      # Don't load any library named lib_private*.so
      file_name_regexp = lib_private.*\\.so

This prevents the tool from loading (and thus comparing) any library
which name matches the pattern "lib_private*.so".

    [suppress_file]
      # Only load libraries name lib_public*.so
      file_name_not_regexp = lib_public.*\\.so

This instructs the tool to only load (and compare) files which name
match the pattern "lib_public*.so".

	* doc/manuals/libabigail-concepts.rst: Document the new
	'suppress_file' directive.
	* include/abg-suppression.h (file_suppression): Define new class.
	(file_suppression_sptr): Define new typedef.
	(is_file_suppression, file_is_suppressed): Declare new functions.
	* src/abg-suppression.cc ():
	(read_file_suppression, is_file_suppression, file_is_suppressed):
	Define new functions.
	(file_suppression::{file_suppression, suppresses_file,
	~file_suppression}): Define new member functions.
	* tools/abidiff.cc (main): If a suppression specification
	suppresses one of the input files, then do not perform the
	comparison.
	* tools/abipkgdiff.cc (compare): If a suppression specification
	suppresses a file that is to be compared, then do not perform the
	comparison.
	* tools/abicompat.cc (create_diff_context): New static function.
	(perform_compat_check_in_normal_mode)
	(perform_compat_check_in_weak_mode): Adjust to take a context in
	parameter.  Do not create a diff context here anymore, do not load
	suppression files here either.
	(main): Use the new create_diff_context to create a diff context
	and initialize it, including loading suppression specifications.
	If any suppression specification suppresses a file to load, then
	do not load perform any compatibility checking.  Adjust
	invocations of perform_compat_check_in_weak_mode and
	perform_compat_check_in_normal_mode to pass the diff context.
	* tests/data/test-diff-suppr/test0-type-suppr-3.suppr: New test
	input.
	* tests/data/test-diff-suppr/test0-type-suppr-4.suppr: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-5.suppr: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-5.txt:
	Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-6.suppr: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-6.txt:
	Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-7.txt:
	Likewise.
	* tests/test-diff-suppr.cc (in_out_specs): Use the new test
	inputs.
	* tests/data/test-abicompat/test0-fn-changed-1.suppr: New test
	input.
	* tests/data/test-abicompat/test0-fn-changed-report-3.txt:
	Likewise.
	* tests/test-abicompat.cc (in_out_specs):: Use the new test
	inputs.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-08 12:39:26 +02:00
Dodji Seketeli
b885e6283f Bug 20015 - support file_name_not_regexp and soname_not_regexp in suppr specs
The supression directives suppress_type, suppress_function and
suppress_variable support the two properties below, among others:

    file_name_regexp = <some-regexp>
    soname_regexp = <some-regexp>

When the regular expression matches either the file name or the
soname, then the suppression directive is activated.

This patch adds the support for these two additional properties for
these suppression directives:

    file_name_not_regexp = <some-regexp>
    soname_not_regexp = <some-regexp>

These activate the current suppression directive if the regular
expression does *NOT* match the file name or soname.

This is very helpful to express change report suppressions like:

    "suppress all ABI change reports for all libraries but those with
    file names (or sonames) with the pattern libfoobar.*"

	* include/abg-comparison.h
	(suppression_base::{get,set}_file_name_not_regex_str): Declare new
	member functions.
	(suppression_base::{get,set}_soname_not_regex_str): Likewise.
	(suppression_base::{names,sonames}_of_binaries_match): Likewise.
	* src/abg-comparison.cc
	(suppression_base::priv::get_file_name_regex): Fix comment.
	(suppression_base::priv::get_file_name_not_regex): New member
	function.
	(suppression_base::priv::get_soname_regex): Fix comment.
	(suppression_base::priv::get_soname_not_regex): New member
	function.
	(suppression_base::{get,set}_file_name_not_regex_str): Define new
	member functions.
	(suppression_base::{get,set}_soname_not_regex_str): Likewise.
	(suppression_base::{names,sonames}_of_binaries_match): Likewise.
	These got factorized out of type_suppression::suppresses_type,
	function_suppression::suppresses_function,
	function_suppression::suppresses_function_symbol,
	variable_suppression::suppresses_variable,
	variable_suppression::suppresses_variable_symbol.
	(type_suppression::suppresses_type): Use the new
	suppression_base::{names,sonames}_of_binaries_match.
	(read_type_suppression): Read the new file_name_not_regexp and
	soname_not_regexp properties.
	(function_suppression::{suppresses_function,
	suppresses_function_symbol}): Use the new
	suppression_base::{names,sonames}_of_binaries_match.
	(read_function_suppression): Read the new file_name_not_regexp and
	soname_not_regexp properties.
	(variable_suppression::{suppresses_variable,
	variable_suppression::suppresses_variable_symbol}): Use the new
	suppression_base::{names,sonames}_of_binaries_match.
	(read_variable_suppression): Use the new
	suppression_base::{names,sonames}_of_binaries_match.
	* doc/manuals/libabigail-concepts.rst: Document the new
	file_name_not_regexp and soname_not_regexp suppression properties.
	* tests/data/test-diff-suppr/test24-soname-report-10.txt: New test
	reference output.
	* tests/data/test-diff-suppr/test24-soname-report-11.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-12.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-13.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-14.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-15.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-16.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-report-9.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-10.txt: New test input.
	* tests/data/test-diff-suppr/test24-soname-suppr-11.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-12.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-13.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-14.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-15.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-16.txt: Likewise.
	* tests/data/test-diff-suppr/test24-soname-suppr-9.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-2.txt: New test
	reference output.
	* tests/data/test-diff-suppr/test29-soname-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-5.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-6.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-7.txt: Likewise.
	* tests/data/test-diff-suppr/test29-soname-report-8.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-2.txt: New test input.
	* tests/data/test-diff-suppr/test29-suppr-3.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-4.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-5.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-6.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-7.txt: Likewise.
	* tests/data/test-diff-suppr/test29-suppr-8.txt: Likewise.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Make this test harness
	run over the new test inputs.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-04-27 23:58:50 +02:00
Dodji Seketeli
2529f84ae0 Bug 19964 - Cannot load function aliases on ppc64
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>
2016-04-25 14:48:11 +02:00
Sinny Kumari
8944ceb9ef Bug 19961 - Distinguish between PI executable and shared library
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>
2016-04-20 17:05:16 +02:00
Dodji Seketeli
f6c182bb56 Ease use of soname_regexp/file_name_regexp in suppr specs
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>
2016-04-16 21:47:20 +02:00
Dodji Seketeli
d06c4cd2ca Fix comments in tests/test-diff-pkg.cc
* tests/test-diff-pkg.cc: Fix the wording of the introductory
	comments.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-03-31 10:13:49 +02:00
Dodji Seketeli
11f5dbaab2 Bug 19885 - Cannot associates a function DIE to a symbol on powerpc64
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>
2016-03-30 20:17:42 +02:00
Dodji Seketeli
67435cf6cd Bug 19867 - abipkgdiff skips symbolic links
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>
2016-03-25 13:52:02 +01:00
Dodji Seketeli
10b029b385 Bug 19844 - Cannot try to canonicalize a type that is being constructed
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>
2016-03-18 18:15:29 +01:00
Dodji Seketeli
d611e96460 Fix potential race condition in test-diff-pkg.cc
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>
2016-03-08 14:34:58 +01:00
Dodji Seketeli
9efa6af3e2 Fix reference to test file in Makefile.am
* tests/data/Makefile.am: Fix bogus reference to
	libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-03-07 15:13:04 +01:00
Dodji Seketeli
326992f0e1 Bug 19780 - abipkgdiff doesn't support parallel execution
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>
2016-03-07 14:15:08 +01:00
Dodji Seketeli
3cf729c3ee Bug 19778 - diff_has_ancestor_filtered_out() loops forever
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>
2016-03-07 12:30:13 +01:00
Dodji Seketeli
ba1b9916ac Forgot to add test2-filtered-removed-fns-v{0,1}.o
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>
2016-03-07 12:29:54 +01:00
Dodji Seketeli
ddc21ed73e Bug 19596 - Suppressed removed symbol changes still considered incompatible
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>
2016-03-04 01:02:46 +01:00
Dodji Seketeli
2bbe75a08a Fixup virtual member functions with linkage and no underlying symbol
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>
2016-02-25 16:49:39 +01:00
Dodji Seketeli
cf8eba68c3 Implement string interning for Libabigail
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>
2016-02-24 15:13:20 +01:00
Dodji Seketeli
9d5b898f28 Make the tree pass distcheck again.
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>
2016-02-20 13:01:26 +01:00
Dodji Seketeli
e62901963f Bug 19658 - Type canonicalization slow for the 2nd binary loaded
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>
2016-02-18 16:06:13 +01:00
Dodji Seketeli
1bb3461d1d Bug 19638 - DWARF reader fails to link clone function to its declaration
There are three mains issues that cause the reported problem.  Let's
look at them closely.

Suppose there is a DIE of a member function Klass::clone_of_foo, which
is a clone of the DIE of the function Klass_foo, which is the concrete
instance of the DIE of the declaration of Klass::foo.

When libabigail's DWARF reader sees the DIE for Klass::clone_of_foo,
it fails to get the context of the declaration of Klass::clone_of_foo
-- which is Klass::foo.

So, in the model built by libabigail, the symbol of
Klass::clone_of_foo never gets associated to Klass::foo.  It thus
looks like Klass::clone is never defined.  It also looks like that
symbol is unreferenced.  From there, a number of bad things happen.
This is the first root cause of the reported problem.  I call it issue
1/.

2/ While looking at this, I noticed that libabigail uses the
underlying symbol name of a given function as the linkage name of that
function, rather than using the value of the DW_AT_linkage_name DWARF
property.  This usually works, until the the function has a symbol
which has several aliases.  In that case, depending on the symbol
alias that is used, a given function can have different linkage names.
This causes problems later at comparison time.  This is issue 2/.

3/ I also noticed that in the libabigail model, even if type Klass
does have all its member functions (including Klass::foo) defined in
in a particular translation unit TU1 , the same Klass in another
translation unit TU2 might not have that Klass::foo defined, just
because that function is not used in TU2.  So after type
canonicalization, if the version of Klass that is kept is the one from
TU2, we end up with a type Klass *NOT* having Klass::foo defined.
Sometimes, it's just that one member function in the canonical type
doesn't have any underlying symbol, whereas the same member function
in another type of the same class of equivalence as the canonical type
does have that an underlying symbol.  This is issue 3/.

To address issue 1/ the patch fixes build_ir_node_from_die, in the
case where a DW_TAG_subprogram DIE is being handled.  It fixes the
case of finding the root interface of the clone of a function
definition.  The patch also fixes a bug in build_function_decl that
prevents it to update the linkage name of a function, *if* that
function already had one.  This was preventing build_function_decl to
adjust the linkage name of a function which is a clone of an original
function which already had a non-empty linkage name.

To address 2/ the patch makes function_decl::get_id return the linkage
name of the function, *if* it exists (rather than primarily returning
the ID of the underlying symbol).

To address 3/ the patch implements the copying of member functions or
underlying function symbols missing from the canonical type -- but
otherwise present in the type that has just been canonicalized.

	* include/abg-ir.h (decl_base::set_linkage_name): Make this member
	function virtual.
	(class_decl::string_mem_fn_ptr_map_type): Define new member type.
	(class_decl::find_member_function): Declare new member function.
	(copy_member_function): Declare new function.  Declare it as
	friend of class_decl.
	(method_decl::set_linkage_name): Declare an overload for this
	virtual function.
	* src/abg-dwarf-reader.cc (build_function_decl): Allow updating of
	linkage_name even if the linkage_name was already defined.
	(build_ir_node_from_die): In the case DW_TAG_subprogram, make the
	lookup of scope of the DIE work even if it has both an abstract
	origin and a specification (DW_AT_abstract_origin and
	DW_AT_specification).
	* src/abg-ir.cc (maybe_adjust_canonical_type): Define new
	function.
	(canonicalize): Use it.
	(function_decl::get_id): Return the linkage name first, if it
	exist.
	(class_decl::priv::mem_fns_map_): New data member.
	(class_decl::find_member_function): Define new member function.
	(class_decl::method_decl::set_linkage_name): Likewise.
	(class_decl::add_member_function): Update the new data member
	class_decl::priv::mem_fns_map_.
	(copy_member_function): Define new static function.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-17 16:30:01 +01:00
Dodji Seketeli
1eecd89ee1 Bug 19619 - failing to suppress added aliased function reports for C++
Libabigail is designed to avoid suppressing a change report about an
added (or removed) function if that function has aliases.  For the
change report to be suppressed, the condition of the suppression
specification must match all the aliases of the symbol of the
function.  This is to avoid suppressing change reports about aliases
by error.

If the binary results from a C program, the name of the function is
the same as the name of its underlying symbol.  So if the condition of
the suppression specification is the property "name_regexp", the value
of the condition can be made to match the names of all the aliases of
the underlying symbol of the function.  In that case, if value of the
property name_regexp does *NOT* match all the aliases, then it's OK
for the "change report suppression sub-system" to avoid suppressing
the change report.

But if the binary results from a C++ program, the name of the function
is *different* from the name of its underlying symbol.  If the
condition of the suppression specification is the property
"name_regexp", there is *NO* way for the user to provide a value which
matches *ANY* of the names of the underlying function symbols while
also matching the name of the function.  So in this case, the "change
report suppression sub-system" should assume that the user wants to
suppress the change reports about all the aliases of the function.

In this problem report, the issue is that in the case of a C++ program
for which the user provided the "name_regexp" property, Libabigail is
expecting the "name_regexp" to match all the aliased symbol
names. Which is not possible.  So the suppression specification is not
suppressing the change report about the added function, just because
the function has an alias.

This patch fixes the issue by taking into account the difference
between languages where the name of the function is the same as the
name of their underlying symbol and languages where it is not.

	* src/abg-comparison.cc
	(function_suppression::suppresses_function): Make the evaluation
	of the "name" and "name_regexp" consider the cases of languages in
	which the function name is the same as the symbol name and the
	case of languages in which it is not.  In the former case, all
	symbol alias names must be matched.  In the latter case, if "name"
	and "name_regexp" match the function name, the suppression
	specification is considered to match the report about the function
	change.  Also, use the elf_symbol::is_main_symbol() predicate to
	test for the symbol being a main symbol, rather than using
	error-prone pointer equality.
	* tests/data/test-diff-suppr/test27-add-aliased-function-0.suppr:
	New test input.
	* tests/data/test-diff-suppr/test27-add-aliased-function-1.suppr: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-2.suppr: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-3.suppr: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-4.suppr: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-report-5.txt: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-v0.cc: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-v0.o: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-v1.cc: Likewise.
	* tests/data/test-diff-suppr/test27-add-aliased-function-v1.o: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-0.suppr: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-1.suppr: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-2.suppr: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-3.suppr: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-4.suppr: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-5.suppr: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-5.txt: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-report-6.txt: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-v0.c: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-v0.o: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-v1.c: Likewise.
	* tests/data/test-diff-suppr/test28-add-aliased-function-v1.o: Likewise.
	* tests/data/Makefile.am: Add the new test material above to the
	source distribution.
	* tests/test-diff-suppr.cc: Add the new test inputs above to this
	test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-13 08:47:41 +01:00
Dodji Seketeli
ef2211831f Use proper WIFEXITED and WEXITSTATUS macros to get exit code
It turns out we were wrongly getting the exit code of some processes
being executed by the "system()" invocation.  The patch uses the
WIFEXITED and WEXITSTATUS macro as documented in the man page for
"system".

	* tests/test-diff-dwarf-abixml.cc (main): Use WIFEXITED and
	WEXITSTATUS macros to get the return code of the abidiff program.
	* tests/test-diff-filter.cc (test_task::perform): Likewise.
	* tests/test-diff-pkg.cc (main): Likewise.
	* tests/test-diff-suppr.cc (main): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-10 22:06:01 +01:00
Dodji Seketeli
4b7e295b20 Bug 19596 - Incorrect exit status for incompatible ABI change
The comparison engine doesn't take virtual offset changes into account
when deciding if a diff node carries an incompatible change.  This is
obviously an oversight.

Fixed thus.

	* include/abg-comparison.h (enum diff_category): Adjust the
	comment for enumerator VIRTUAL_MEMBER_CHANGE_CATEGORY; changes of
	this category are incompatible ABI changes.
	(corpus_diff::diff_stats::num_func_with_virtual_offset_changes):
	Declare new accessors.
	* src/abg-comparison.cc
	(corpus_diff::diff_stats::priv::num_func_with_virt_offset_changes):
	New data member.
	(corpus_diff::diff_stats::priv::priv): Initialize the new data
	member.
	(corpus_diff::diff_stats::num_func_with_virtual_offset_changes):
	Define new accessors.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats): Use the
	new accessor to set the number of functions with virtual offset
	changes onto the stats data structure.
	(corpus_diff::has_incompatible_changes): Take functions with
	virtual offset changes into account.
 	* tests/test-abidiff-exit.cc: New test harness to test for exit
	codes of abidiff.
	* tests/Makefile.am: Build the new test harness runtestabidiff
	from the test-abidiff-exit.cc source file.
	* tests/data/test-abidiff-exit/test1-voffset-change-report0.txt:
	New reference test output.
	* tests/data/test-abidiff-exit/test1-voffset-change-v0.cc: New
	test input source code.
	* tests/data/test-abidiff-exit/test1-voffset-change-v0.o: New test input.
	* tests/data/test-abidiff-exit/test1-voffset-change-v1.cc: New
	test input source code.
	* tests/data/test-abidiff-exit/test1-voffset-change-v1.o: New test input.
	* tests/data/Makefile.am: tests/data/Makefile.am: Add the new test
	inputs above to the source distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-10 21:31:53 +01:00
Dodji Seketeli
31aef952c8 Fix synthesizing of reference type
Libabigail fails to synthesize a non-existing reference type to an
existing type.

This is similar to the previous commit "2f88edd Fix synthesizing of
pointer type" which, obviously dealt with pointer types.

This patch adds support for synthesizing a reference type to an
existing type.

	* src/abg-ir.cc (synthesize_type_from_translation_unit): Support
	synthesizing reference types.
	* tests/data/test-abicompat/libtest9-fn-changed-v0.so: Add new
	test input.
	* tests/data/test-abicompat/libtest9-fn-changed-v1.so: Likewise.
	* tests/data/test-abicompat/test9-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test9-fn-changed-app.cc: : Likewise.
	* tests/data/test-abicompat/test9-fn-changed-report-0.txt: Likewise.
	* tests/data/test-abicompat/test9-fn-changed-v0.cc: Likewise.
	* tests/data/test-abicompat/test9-fn-changed-v0.h: Likewise.
	* tests/data/test-abicompat/test9-fn-changed-v1.cc: Likewise.
	* tests/data/test-abicompat/test9-fn-changed-v1.h: Likewise.
	* tests/data/Makefile.am: Add the new material to source
	distribution.
	* tests/test-abicompat.cc (in_out_specs): Add the new test inputs
	to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-04 11:26:22 +01:00
Dodji Seketeli
2f88edd3b3 Fix synthesizing of pointer type
Libabigail fails to to synthesize a non-existing pointer type to an
existing type.

This makes abicompat fail in weak mode when trying to detect changes
to a function type where the parameter is a pointer to a structure
which changed.  In the application, the function is invoked and a
pointer to the structure is passed to it.  It appears that the type of
structure is defined in the debug info of the application, but not the
pointer to that structure.  So abicompat needs to synthesize that
pointer to struct in order to synthesize the type of the function, and
so, compare it to the type of the function coming from the library.

It appears that synthesizing a pointer type (to an existing type) is
not supported.  Only synthesizing qualified type was supported.

This patch adds support for that and thus fixes the abicompat test
case that is attached.

	* include/abg-ir.h: Update copyright.
	* src/abg-ir.cc (synthesize_type_from_translation_unit): Support
	synthesizing pointer types.

	* tests/data/test-abicompat/libtest8-fn-changed-libapp-v0.so: New
	test input.
	* tests/data/test-abicompat/libtest8-fn-changed-libapp-v1.so: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-app: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-app.c: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-libapp-v0.c: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-libapp-v0.h: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-libapp-v1.c: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-libapp-v1.h: Likewise.
	* tests/data/test-abicompat/test8-fn-changed-report-0.txt: Likewise.
	* tests/data/Makefile.am: Add the new test input files to source
	distribution.
	* tests/test-abicompat.cc (in_out_specs): Add the new test inputs
	above to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-03 13:00:51 +01:00
Dodji Seketeli
066ebbdf0e Bug 19204 - libabigail aborts on DWARF referencing non-existing DIE
In this bug the DWARF reader tries to get the parent of a DIE
(referred-to by its offset) which is not defined in the debug info.
The DIE is not defined, but it's referred-to by another DIE of the
debug info.  This definitely looks like a faulty DWARF.

The DWARF reader aborts because, obviously, it cannot get the parent
DIE of a DIE that is not defined.

This patch changes the behaviour of the DWARF reader in this case.
Rather than aborting, the DWARF reader just drops the DIE (which
refers to a non-existing DIE) on the floor.  It thus do not abort on
such faulty DWARF anymore.

	* src/abg-dwarf-reader.cc (get_parent_die): If we couldn't find
	the parent of a given DIE, return false, do not abort.  Also,
	assert that if we don't find the parent of a DIE in the main debug
	info, we don't find it in the alternate debug info either (and
	vice versa).  This is because I'd like to abort on cases where we
	look for a DIE in the wrong debug info; those cases are likely to
	be hint that the DWARF reader is doing something wrong which ought
	to be investigated and fixed.
	(get_scope_for_die): If we couldn't get the parent of the DIE,
	then return a nil scope.
	* tests/data/test-types-stability/pr19204-libtcmalloc.so.4.2.6-xlc:
	New test binary input.
	* tests/data/Makefile.am: Add the new binary test input to the
	source distribution.
	* tests/test-types-stability.cc (elf_paths): Account for the new
	binary input.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-21 10:48:32 +01:00
Dodji Seketeli
640b3a2f59 Bug 19141 - Libabigail doesn't support common ELF symbols
Libabigail's internal representation of elf symbols fails to account
for common symbols in relocatable files.  There can be several common
symbols of the same name (defined in a section of SHN_COMMON kind).
In that case, Libabigail wrongly considers these multiple instances of
the same common symbol as being alias, and that breaks some
basic assumptions about aliases.  Oops.

This patch adds support for the common symbols (and the fact that
relocatable files can have several instances of the same common
symbol) and amends the ELF reader to make it properly represent those.
	* include/abg-ir.h (elf_symbol::elf_symbol): Take a new flag to
	say if the symbol is common.
	(elf_symbol::{is_common_symbol, has_other_common_instances,
	get_next_common_instance, add_common_instance}): New member functions.
	* src/abg-ir.cc (elf_symbol::priv::{is_common_,
	next_common_instance_): New data members.
	(elf_symbol::priv::priv): Adjust.
	(elf_symbol::{elf_symbol, create}): Take a new flag to say if the
	symbol is common.
	(textually_equals): Adjust to account for symbol common-ness.
	(elf_symbol::{is_common_symbol, has_other_common_instances,
	get_next_common_instance, add_common_instance}): Define new member
	functions.
	(elf_symbol::add_alias): Drive-by fix; compare symbols using
	pointer value.  Value comparison is not necessary.
	* src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab)
	(lookup_symbol_from_gnu_hash_tab, lookup_symbol_from_symtab)
	(read_context::lookup_elf_symbol_from_index): Adjust the creation
	of the symbol to account for common-ness.
	(read_context::load_symbol_maps): Recognize instances of a given
	common symbol and represent them as such.  Do not mistake this
	with symbol aliases.
	* src/abg-reader.cc (build_elf_symbol): Adjust the creation of the
	symbol to account for common-ness.
	* src/abg-writer.cc (write_elf_symbol): Adjust symbol
	serialization to account common-ness.
	* tests/data/test-types-stability/pr19141-get5d.o: Add new test
	binary input.
	* tests/data/test-types-stability/pr19142-topo.o: Likewise.
	* tests/data/Makefile.am: Add the new test inputs to source distribution.
	* tests/test-types-stability.cc (elf_paths): The the new test
	inputs into account.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-20 13:37:52 +01:00
Dodji Seketeli
c3869ecc7b Bug 19434 - invalid character in attribute value
* include/abg-tools-utils.h (string_is_ascii_identifier): Declare
	new function.
	* src/abg-tools-utils.cc (string_is_ascii_identifier): Define new function.
	* src/abg-dwarf-reader.cc (build_function_type): Discard parameter
	name if it's made of non-identifier ascii characters.
	* tests/data/test-types-stability/pr19434-elf0: New test binary input file.
	* tests/data/Makefile.am: Add the new test input to source distribution.
	* tests/test-types-stability.cc: Test the new test input into account.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-18 18:23:19 +01:00
Dodji Seketeli
5e171c530c Sort the tests run in tests/ by running the slowest ones first
This speeds up the tests when they are run in parallel.

	* tests/Makefile.am: Sort the tests  by running the slowest ones
	first.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-18 18:23:18 +01:00
Dodji Seketeli
f275939df2 Use worker threads pattern to speed up some tests
We are going to need to speed up more and more tests, and coding directly
with libpthread for that can be tedious and bug-prone.  So I devised an
implementation for the worker threads design pattern instead, and used
it to speed up some tests.

	* include/Makefile.am: Add the new abg-workers.h to source
	distribution.
	* include/abg-workers.h: New file.
	* src/Makefile.am: Add the new abg-worker.cc to source
	distribution.
	* src/abg-workers.cc: New file.
	* tests/test-utils.cc: Update copyright.  Make get_src_dir() and
	get_build_dir() return a const char*, as opposed to returning a
	string.  Make that const char reside in thread local storage, so
	that two concurrent threads can safely call these functions in
	parallel, without any race.
	* tests/test-utils.h: Make get_src_dir() and get_build_dir()
	return a const char*, as opposed to returning a string.
	* tests/test-abicompat.cc: Update copyright.  Adjust for
	get_src_dir() and get_build_dir() change.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-pkg.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-lookup-syms.cc: Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/test-read-write.cc: Likewise.
	* tests/test-types-stability.cc: Likewise.  Use the new task queue
	type to run these tests in parallel.
	* tests/test-diff-filter.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-18 18:23:18 +01:00
Ondrej Oprala
c8c7a3b5e7 Escape the value of the filepath attribute.
* src/abg-writer.cc (write_location): Sanitize the filepath with
	xml::escape_xml_string().
	(write_translation_unit): Likewise.
	(write_corpus_to_native_xml): Likewise.
	* tests/data/test-types-stability/pr19433-custom0: Add a new test file.
	* tests/test-types-stability.cc: Add the test file to the test harness.
	* tests/data/Makefile.am: Add the new test file to the list.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2016-01-18 12:18:19 +01:00
Dodji Seketeli
5c8c049e70 Bug 19138 - Failure to relate variables address from DWARF and ELF
In this problem report libabigail's DWARF reader wrongly looks up the
address of variables (that it got from DWARF) in the .bss section of
the ELF file.  But then, in these files (generated by the Intel C++
compiler) the variables we are looking at have their addresses in the
.data1 section.

This patch changes the DWARF/ELF reader to make it look for variable
addresses in .data, .data1, .rodata and .bss sections, as it should
be.

	* include/abg-dwarf-reader.h (elf_type::ELF_TYPE_RELOCATABLE): New
	enumerator.
	* src/abg-dwarf-reader.cc (find_section): Factorize this from ...
	(find_text_section, find_bss_section): ... these.
	(find_rodata_section, find_data_section, find_data1_section):
	Define new static functions.
	(elf_file_type): Move this static function definition up.
	(read_context::{get_elf_file_type, address_is_in_section,
	get_data_section_for_variable_address}): New member functions.
	(read_context::maybe_adjust_fn_sym_address): Adjust comment.
	Adjust to use the new
	read_context::get_data_section_for_variable_address().
	* tests/data/test-types-stability/pr19138-elf0: New test input
	binary.
	* tests/data/Makefile.am: Add the new test input binary to the
	test suite.
	* tests/test-types-stability.cc (elf_paths): Take it into account.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-01-08 22:38:58 +01:00