Commit Graph

1520 Commits

Author SHA1 Message Date
Dodji Seketeli
b49119584b Add missing deep comparison operators for {function, method}_decl_sptr
It turned out we were missing deep comparison operators for smart
pointers to function_decl and method_decl.  Because of coming patches
that compare virtual member functions as part of comparing classes, we
need these deep comparison operators.

	* include/abg-ir.h (operator==): Declare two new overloads for
	function_decl_sptr an method_decl_sptr.
	* src/abg-ir.cc (operator==): Define two new overloads for
	function_decl_sptr an method_decl_sptr.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 21:00:54 +01:00
Dodji Seketeli
0af65e6364 Fix performance regression while analyzing libjvm.so
abidiff libjvm.so libjvm.so is taking forever in the master branch
these days.  At some point it was taking ~ 15 minutes and 15GB of RAM
on a non-optimized build.

Profiling of CPU usage showed that sorting virtual member
functions of a class whenever a new virtual member function is added
was the hot spot.

This patch now sorts virtual member functions once right after the
type was canonicalized.  The patch adds a virtual function
type_base::on_canonical_type_set() that is invoked right after the
canonical type is set for a given type.  class_decl gets its own
version of that virtual function: class_decl::on_canonical_type_set.
In that function, the patch does sort the virtual member functions of
the current class_decl.

Now with this patch, abidiff is still taking around 15 minutes but it
consumes less than 12GB of ram.  This means the memory consumption was
reduced by 20%.  abipkgdiff performs on 16:30 minutes and in less than
12GB of RAM as well.  All these times are measured on a non-optimized
build.

	* include/abg-ir.h ({type_base,
	class_decl}::on_canonical_type_set): Declare new virtual member
	function.
	* src/abg-ir.cc (type_base::on_canonical_type_set): Define new
	virtual member function that does nothing.
	(class_decl::on_canonical_type_set): Define new virtual member
	function that sorts the virtual member functions of class_decl.
	(canonicalize): Invoke type_base::on_canonical_type_set when the
	canonical type is set.
	(fixup_virtual_member_function): Don't sort virtual member
	functions here.
	* src/abg-dwarf-reader.cc (finish_member_function_reading): Do not
	sort virtual member functions here.
	* 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/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 19:25:36 +01:00
Dodji Seketeli
9dc07f5534 Update copyright notice for abg-fwd.h, abg-ir.h and test-abidiff.cc
* include/abg-fwd.h: Adjust copyright.
	* include/abg-ir.h: Likewise.
	* tests/test-abidiff.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 15:36:20 +01:00
Dodji Seketeli
192c8d00ff Remove unused functions from abg-ir.cc
* src/abg-ir.cc (convert_node_to_decl): Remove specializations for
	class_decl_sptr, type_base_sptr and var_decl_sptr.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 08:57:55 +01:00
Dodji Seketeli
08e760221b Support Linux Kernel ABI whitelist files
Enterprise Linux (at least) kernels come with ABI whitelist files that list the
names of the set of functions to be considered when looking at the ABI
exposed by the kernel to its modules.

This patch adds a new --linux-kernel-abi-whitelist option to abidiff
so that it drops changes that relate to functions that are *NOT*
defined in the whitelist.

The patch reads the whitelist file and generates one or several
instances of function_suppression that are applied when the two
binaries are loaded.

	* include/abg-suppression.h
	(function_suppression::function_suppression): Make the declaration
	of the default constructor public.
	* src/abg-suppression-priv.h (function_suppression::priv::priv):
	Declare a default constructor.
	* src/abg-suppression.cc
	(function_suppression::function_suppression): Define default
	constructor.
	* include/abg-tools-utils.h
	(gen_suppr_spec_from_kernel_abi_whitelist): Declare new function.
	* src/abg-tools-utils.cc
	(gen_suppr_spec_from_kernel_abi_whitelist): Define new function.
	* tools/abidiff.cc (options::kernel_abi_whitelist_paths):
	(display_usage): Display a help string for the new
	--linux-kernel-abi-whitelist option.
	(parse_command_line): Parse the --linux-kernel-abi-whitelist from
	the command line.
	(maybe_check_suppression_files): Check the presence of the kernel
	abi whitelist files.
	(set_suppressions): Generate suppression specifications from the
	whitelist files.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-06 12:41:57 +01:00
Dodji Seketeli
fadfa1a6f6 Support Linux Kernel binaries
This patch teaches the ELF/DWARF reader of libabigail to load special
ELF sections that are specific to Linux Kernel binaries (either
vmlinux or linux kernel modules).

The patch creates a new flag that tells the ELF reader that it needs
to consider the input binary as a Linux Kernel binary.  This is the
new 'Linux Kernel mode'.

In this linux kernel mode, the reader expects sections that are named
__ksymtab and/or __ksymtab_gpl sections.  Those sections contain
indexes (of ELF symbols described in the normal ELF symbol table) of
exported ELF symbols that are specifically marked by developers using
EXPORT_SYMBOL or EXPORT_SYMBOL_GPL macros.  These are symbols of
global variables and functions defined and meant to be used by kernel
modules.  They constitute the interface exported by the Linux Kernel
to its modules.  So the patch only exports the publicly defined and
exported ELF symbols that are also listed in __ksymtab and
__ksymtab_gpl sections.

The patch also fixes and re-organizes things left and right so that
this new mode works in a well integrated manner with the other parts
of the reader:

  - The load address of the binary is no more assumed to be the load
    address specified by the program header that is at offset zero.
    This is usually the case for user-space programs.  To handle Linux
    Kernel binaries, the load address is now the one specified by the
    program header that is at the smallest offset.

  - The patch now tries to populate the various symbol maps only when
    necessary.  That way, the new symbol maps defined for the ksymtab
    and ksymtab_gpl section are also loaded only when necessary; that
    is, when in Linux Kernel mode.

  - The patch (more) agressively suppresses non-member functions or
    variables that are not declarations and that have no associated
    ELF symbol.

The patch knows how to recognize and read relevant ELF symbol
information from __ksymtab and __ksymtab_gpl sections.

The patch makes abidiff and abidw detect that a binary is a
Linux Kernel binary (either a vmlinux or a module).  It does this by
detecting the presence of the speciall __ksymtab_strings section.

If it detects that a binary is a Linux Kernel binary then it only
considers functions and variables which are defined and exported in
the sense of ELF *AND* which ELF symbols are listed in the __ksymtab
and __ksymtab_gpl sections.

If users want abidiff and abidw to consider their input binaries as
normal ELF binaries then they can use the option --no-linux-kernel-mode.

	* include/abg-dwarf-reader.h (create_read_context): Take a new
	flag to say if the context is to read an ELF binary in linux
	kernel mode.
	* src/abg-dwarf-reader.cc (typedef address_set_type)
	(address_set_sptr): New typedefs.
	(get_binary_load_address):  The load address of the binary is
	the load address specified by the program header that is at the
	smallest offset; not by the program header that is at offset zero.
	(read_context::{ksymtab_section_, ksymtab_gpl_section_,
	linux_exported_fn_syms_, linux_exported_var_syms_,
	linux_exported_gpl_fn_syms_, linux_exported_gpl_var_syms_,
	load_in_linux_kernel_mode_}): New data members.
	(read_context::read_context): Initialize ksymtab_section_,
	ksymtab_gpl_section_ and load_in_linux_kernel_mode_.
	(read_context::{find_symbol_table_section, find_opd_section,
	lookup_elf_fn_symbol_from_address,
	lookup_elf_var_symbol_from_address, get_function_address,
	get_variable_address}): Make these const.
	(read_context::{find_ksymtab_section, find_ksymtab_gpl_section,
	lookup_elf_symbol_from_address, function_symbol_is_exported,
	variable_symbol_is_exported, linux_exported_fn_syms,
	create_or_get_linux_exported_fn_syms, linux_exported_var_syms,
	create_or_get_linux_exported_var_syms, linux_exported_gpl_fn_syms,
	linux_exported_gpl_var_syms,
	create_or_get_linux_exported_gpl_fn_syms,
	linux_exported_gpl_var_syms,
	create_or_get_linux_exported_gpl_var_syms, architecture_word_size,
	load_kernel_symbol_table, load_ksymtab_symbols,
	load_ksymtab_gpl_symbols,
	load_linux_specific_exported_symbol_maps,
	load_in_linux_kernel_mode}): New member functions.
	(read_context::read_int_from_array_of_bytes): Factorize this
	new member function out of ...
	(read_context::{lookup_ppc64_elf_fn_entry_point_address}):
	... this.  Make this function const too.
	(read_context::read_uint64_from_array_of_bytes): New function.
	Uses read_int_from_array_of_bytes above.
	(read_context::{fun_entry_addr_sym_map_sptr}): Try to load symbol
	maps only when it's necessary.
	(read_context::elf_architecture_is_big_endian): Fix logic.
	(read_context::{var_addr_sym_map}):  Express the const variant in
	terms of the non-const one.  In the non-const one, load the map
	only when necessary.
	(read_context::load_symbol_maps_from_symtab_section): Renamed
	load_symbol_maps into this.
	(read_context::is_linux_kernel_binary): Define new member
	function.
	(read_context::{function, variable}_symbol_is_exported): If we are
	not prevented from considering loading in linux kernel mode, then
	just looking at a linux kernel binary makes us consider the
	special kernel sections.
	(read_debug_info_into_corpus): Likewise.
	(build_ir_node_from_die): Take a new flag that says if the ir node
	is a declaration required by another concrete IR node.
	(enum read_context::kernel_symbol_table_kind): New enum.
	(read_context::load_symbol_maps): Support loading linux kernel
	specific sections too.
	(build_var_decl): Use the new
	read_context::variable_symbol_is_exported.
	(function_is_suppressed): Suppress non-member functions or
	variables that are not declarations and that have no symbol.
	(variable_is_suppressed, build_var_decl_if_not_suppressed): Take a
	new flag that says if the variable is a declaration required by a
	concrete variable.  If non member variable that is a declaration
	is not the specification of another concrete variable, then it's
	suppressed.
	(add_fn_symbols_to_map, add_var_symbols_to_map): New function
	definitions.
	(read_debug_info_into_corpus): If we are reading linux kernel or
	linux kernel modules, only set explicitely exported symbols (in
	the linux kernel binary sense) as exported function or variable
	symbols.
	(create_read_context): Take a new flag to say if the context is to
	read an ELF binary in linux kernel mode.
	* tools/abidiff.cc (options::options): Initialize
	options::linux_kernel_mode to true.
	(display_usage): Display usage of the --no-linux-kernel-mode option.
	(parse_command_line): Parse the --no-linux-kernel-mode option.
	* tools/abidw.cc (options::options): Initialize
	options::linux_kernel_mode to true.
	(display_usage): Display usage of --no-linux-kernel-mode option.
	(parse_command_line): Parse the --no-linux-kernel-mode option.
	* doc/manuals/abidiff.rst: Document the new --no-linux-kernel-mode
	options.
	* doc/manuals/abidw.rst: Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.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: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-06 12:35:22 +01:00
Dodji Seketeli
3d267a6fbf Add debug routines to dump locations to a stream
* src/abg-writer.cc (dump_location): Define new function and one
	overload.
	(dump_decl_location): Re-write in terms of the new dump_location.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-06 01:48:33 +01:00
Dodji Seketeli
7a313fc9c9 Better de-duplicate classes, unions, enums in non-odr contexts
When reading an ELF/DWARF binary that doesn't support the One
Definition Rule[1] (aka ODR), type de-duplication is done on a
per-translation unit basis only.  That means that a type definition
must be unique only in a given translation unit, in that case.

[1]: https://en.wikipedia.org/wiki/One_Definition_Rule

When handling big C binaries like the Linux Kernel, this implies a lot
of type duplication still, as the same type can be re-defined in a lot
of different translation units.

This patch tries to de-duplicate types on a per-corpus basis, even in
cases where the ODR doesn't apply.  It does so by noting that if two
types of the same kind and name are seen in two different translation
units and yet have the same source location (are defined in the same
spot) then they are the same type.

The patch does this for class, union and enum types as these seem to
be the kinds of types which are duplicated the most and thus consume
the most memory and later take the most time to canonicalize.  In a
subsequent patch, we might want to try to de-duplicate typedef types
too, and see if gain anything.

Comparing two linux kernels shows that with this patch, we come back
to a speed (and memory consumption) that is comparable to when we were
considering C-based binaries as being suited to our (too aggressive)
ODR-based type de-duplication algorithm.

Below are the output of the comparison measured with /usr/bin/time
with the aggressive ODR-based type de-duplication algorithm and with
this patch.  We compare the vmlinux binary coming from the package
kernel-3.10.0-515 against the one from kernel-3.10.0-327.el7.x86_64.
We use the kabi whitelists provided by the relevant
kernel-abi-whitelists packages for these kernels to restrict the
comparison to a meaningful subset of interfaces.

52.66user 0.64system 0:53.34elapsed 99%CPU (0avgtext+0avgdata 944416maxresident)k 0inputs+48outputs (0major+250750minor)pagefaults 0swaps

vs:

51.04user 0.87system 0:51.91elapsed 100%CPU (0avgtext+0avgdata 972560maxresident)k
0inputs+232outputs (0major+279983minor)pagefaults 0swaps

The full invocation and results are available at:

http://people.redhat.com/~dseketel/kabidiff/vmlinuz-3.10.0-327.el7.x86_64--vmlinuz-3.10.0-515.el7.x86_64.diff.whitelisted.with-unions.txt

vs

http://people.redhat.com/~dseketel/kabidiff/vmlinuz-3.10.0-327.el7.x86_64--vmlinuz-3.10.0-515.el7.x86_64.diff.whitelisted.with-unions.with-non-odr-support.txt

Note that to be able to compare the two kernels, the current tree must
contain the necessary patches that make libabigail understand Linux
Kernel binaries.

	* src/abg-dwarf-reader.cc (build_enum_type)
	(add_or_update_class_type, add_or_update_union_type): When the ODR
	is not relevant, use the location of the type to detect if two
	enum, class or union types of the same name actually represent the
	same type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-06 01:43:57 +01:00
Dodji Seketeli
bdac61cc32 Adjust some reference outputs of the test-read-dwarf test harness
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-06 01:41:09 +01:00
Ondrej Oprala
5aff747c5e Bug 18754 - Add the "--no-added-syms" option to abidiff
With this option, abidiff is now able to filter out added
symbols just like abipkgdiff is.

	* doc/manuals/abidiff.rst: Document the new --no-added-syms
	option.
        * tools/abidiff.cc (struct options): Add show_added_syms and
        set it to true by default.
        (display_usage): Document the new options --no-added-syms. If
        this is the only suppression option specified, it is equivalent
        to specifying --show_{changed,deleted}_{fns,vars} as arguments
        to abidiff. If any of those options are specified before
        --no-added-syms, then it has no effect.
        (parse_command_line): Parse the new option and set
	show_added_{fns,vars,syms} and show_all_{fns,vars} to false if
	--no-added-syms is specified.
        * tests/test-diff-filter.cc: Add a test for the new option.
        * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
        Reference results for the new test.
        * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-1.txt:
        Likewise.
        * tests/data/Makefile.am: Add the above test files to the list of
        test data.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 13:44:25 +01:00
Dodji Seketeli
d198b27b64 Update copyright year on a bunch of files
* include/abg-corpus.h: Update copyright year to 2017.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidw.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:51:49 +01:00
Dodji Seketeli
bf138a22c3 [apidoc] Allow brief description at the top of class description pages
* doc/api/libabigail.doxy: Don't disable "brief member desc".

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:51:38 +01:00
Dodji Seketeli
4063dfe487 Misc style fixes
* include/abg-corpus.h: Remove corpus_sptr typedef. It's in
	abg-fwd.h now.
	* src/abg-ir.cc: Remove some unnecessary vertical space.
	* src/abg-reader.cc (build_function_decl): Cleanup some asserts.
	* src/abg-writer.cc (write_function_type): Each the inspection of
	the type id from within the debugger.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:51:30 +01:00
Dodji Seketeli
2d53328bf4 Misc comments and apidoc fixes
* src/abg-dwarf-reader.cc (lookup_symbol_from_gnu_hash_tab): Fix
	typo in comment.
	* tools/abicompat.cc (perform_compat_check_in_weak_mode): Better
	comments.
	* tools/abidw.cc (dislay_usage): Fix white spaces.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>

Conflicts:
	tools/abidw.cc
2017-01-05 12:51:08 +01:00
Dodji Seketeli
b23abed949 Speedup set_member_is_static
set_member_is_static dominates some performance profile because that
function compares data members before their types are canonicalizing.
This means the comparison is done structurally.  So it's potentially
super long.

This patch fixes the issue by comparing data members by just looking at
their names, and that should be enough.

	* src/abg-ir.cc (set_member_is_static): When comparing data
	members, consider only their names.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:47:20 +01:00
Dodji Seketeli
b8452d2d59 Avoid unnecessary updates to type lookup maps
In class_or_union::set_is_declaration_only we should update the type
lookup maps only when a class type that was previously a
declaration-only type is now a defined type.  Otherwise, updating the type
lookup maps is unnecessary and profiling shows that it takes a
significant amount of time.

This patch does away with the unnecessary attempts to update type
lookup maps.

	* src/abg-ir.cc (class_or_union::get_is_declaration_only): Try
          to update the type maps only when a declaration-only class
          type is now defined.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:47:20 +01:00
Dodji Seketeli
7c004d6922 Update tests/data/test-read-dwarf/*.abi files
After the preceding patch series to handle ABI corpora in which the
ODR is not applicable (and the inevitable fallouts) this patch updates
the reference output for the test-read-dwarf test harness.

	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:39:41 +01:00
Dodji Seketeli
f88dbad75d Update tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi
After the preceding patch series to handle ABI corpora in which the
ODR is not applicable (and the inevitable fallouts) this patch updates
the reference output for the test-diff-dwarf-abixml test harness.

	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Update.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:35:18 +01:00
Dodji Seketeli
ef3ecb295c [abixml writer] Make sure all function types are emitted
The abixml writer forgets to emit some function types that are only
referenced by other types.  Fixed thus.

Note that the necessary adjustment to reference outputs of abidw in
the regression test suite is not provided with this patch to ease
backporting.  Those adjustments are in a patch that comes at the end
of this patch series.

	* src/abg-writer.cc (write_translation_unit): Fix logic to avoid
	forgetting referenced function types.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:26:20 +01:00
Dodji Seketeli
f4a4794f29 [abixml writer] Fix comparison of pointer to types
When two type pointers designate two types with the same pretty
printed representatin don't already have an associated type id, the
comparison code was mistakenly associating them with empty type id.

This patch fixes that.

Note that the necessary adjustment to reference outputs of abidw in
the regression test suite is not provided with this patch to ease
backporting.  Those adjustments are in a patch that comes at the end
of this patch series.

	* src/abg-writer.cc (type_ptr_comp::operator()): Do not add an
	empty type id string to the type -> type id map when the entry for
	a given type is empty.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:26:20 +01:00
Dodji Seketeli
2e3a4dfb67 [dwarf-reader] Don't early canonicalize function types
Make sure we don't early-canonicalize function types.  We need to wait
after the end of building the ABI corpus before canonicalizing these.

Normally this should be taken care of by using
type_has_non_canonicalized_subtype but there are cases where that
function does not detect that a type has sub-types that are not
canonicalized.

Fixed thus.

	* src/abg-dwarf-reader.cc (maybe_canonicalize_type):
	Late-canonicalize function types.

signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:26:20 +01:00
Dodji Seketeli
ab37f767b7 Fix qualified name caching for some types
When ::get_qualified_name() is invoked for some types, the value is
cached for performance reasons.

One thing to keep in mind is that the structure of a type can change
between the time when the type is first built and the time when it's
canonicalized.  This is because the type can be built progressively,
with sub-types being added over time until the type is fully built.
Then it can be canonicalized.

So if ::get_qualified_name is invoked on a non-canonicalized type and
the result is cached, then that result might not reflect the state of
the type *after* its canonicalized.  So the cached value might be
wrong.

To address that issue, the solution is to *not* cache the result of
::get_qualified_name() until the type is canonicalized.  After the
type is canonicalized and so we know the structur of the type won't
change, then the result of ::get_qualified_name is cached.

And this is what this patch does for qualified, pointer and array
types.

Note that the necessary update to the regression test suite is not
provided with this patch.  It's provided by a separate patch at the
end of the current series of patches.

	* src/abg-ir.cc ({qualified, pointer,
	array}_type_def::get_qualified_name): Don't cache internal and
	non-internal qualified name when the type is not canonicalized.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:26:20 +01:00
Dodji Seketeli
bf62a050c7 Cleanup ODR-based type canonicalization optimization gating logic
During type canonicalization we use an ODR-based optimization which
consists of saying that if two types of the same kind have the same
name and are defined in the same ABI corpus, then they are the same
type -- whithout needing to actually perform a structural comparison
of both types.  This speeds up type canonicalization greatly for types
that are duplicated in the ABI corpus.

The condition to apply that ODR-based optimization is basically that
the binary we are looking at must be in C++.

This patch just makes that condition clearer.

	* src/abg-ir.cc (type_base::get_canonical_type_for): Make it clear
	that the ODR-based optimization is allowed only on C++ ABI
	corpora.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:26:20 +01:00
Dodji Seketeli
6734da6a04 Fix a typo in method name computation
It turns out we forget a "return" keyword when we want to return the
name of a method.  Ooops.

Fixed thus.

Please note that this patch doesn't come with its necessary update to
the tests/data/test-read-dwarf/test9-pr18818-clang.so.abi and
tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi
files.  Those updates to regression tests are coming in a subsequent
patch.

	* src/abg-ir.cc (get_method_type_name): Really return the method
	name.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:26:20 +01:00
Dodji Seketeli
e95f8cbac2 Update 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
After the preceding patch series to handle ABI corpora in which the
ODR is not applicable (and the inevitable fallouts) this patch updates
the reference output for the test-diff-pkg test harness.

	* 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: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:23:39 +01:00
Dodji Seketeli
772414848e Update tests/data/test-read-write/test27.xml
After the preceding patch series to handle ABI corpora in which the
ODR is not applicable (and the inevitable fallouts) this patch updates
the reference output for the test-read-write test harness.

	* tests/data/test-read-write/test27.xml: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:22:54 +01:00
Dodji Seketeli
1fcdebe47a [dwarf-reader] Handle per translation-unit type de-duplication
Until now, when the elf/dwarf reader builds ABI artifacts, it performs
type de-duplication by considering that a type with a given name should
be defined only once in a given ABI corpus.  This is per-corpus
de-duplication.

The problem with that approach is that it assumes that the binary
respects the One Definition Rule[1], aka ODR.  But then many non-C++
binaries don't respect the ODR.

So, for non-c++ binaries, we shouldn't assume the ODR.  We should be
able to assume a per translation unit (aka per-tu) de-duplication.
That is, consider that a type with a given name is defined just once
in a given translation unit.  Or perform no de-deplication at all,
depending on the kind of type we are looking at.

And this is what this patch does.  It allows the ELF/DWARF reader to
perform per-tu type de-duplication by assuming that it's only in a given
translation unit that a type definition must be unique.  It also allows it
perform no de-duplication at all for some kind of types.

In practice, function types are de-duplicated on a per-tu basis if ODR
is not relevant, otherwise, they are de-duplicated on a per-corpus
basis when ODR is relevant.

For most of the other types, if ODR is not relevant, then no
de-duplication is performed at all.  Otherwise, for these types, if
ODR is relevant, per-corpus de-duplication is performed.

	* src/abg-dwarf-reader.cc
	(read_context::per_tu_name_artefacts_map_): New data member.
	(read_context::clear_per_translation_unit_data): Clear the new
	read_context::per_tu_name_artefacts_map_.
	(read_context::associate_die_to_decl): Take a flag to say if we
	should associate a DIE to its representation and another one to
	say if the association should be done per-tu or per-corpus.
	(read_context::lookup_{type_artifact, artifact}_from_die): Update
	apidoc.
	(read_context::lookup_artifact_from_die_representation): Likewise.
	(read_context::{associate_die_to_artifact_by_repr,
	associate_die_to_artifact_by_repr_internal,
	associate_die_to_type}): Take a flag to say if the associating
	should be done on a per-tu basis.
	(read_context::lookup_{type_artifact, artifact}_from_die_per_tu):
	New member functions.
	(read_context::{lookup_artifact_from_per_tu_die_representation,
	odr_is_relevant}): Likewise.
	(build_enum_type, add_or_update_class_type)
	(add_or_update_union_type): If ODR is not relevant, do not perform
	per-corpus de-duplication.
	(build_pointer_type_def, build_typedef_type): Do not associate the
	type to its representation as these kinds of typs are not
	de-duplicated.
	(build_function_type):  If ODR is not relevant, perform per-tu
	de-duplication.  When ODR is relevant, per-corpus de-duplication
	is performed.
	(build_or_get_fn_decl_if_not_suppressed): Function decls are
	always de-duplicated per-corpus.
	(build_ir_node_from_die): For data members, do not update the die
	representation map as data members are not de-duplicated.  Do not
	do it for function decls either.

[1]: https://en.wikipedia.org/wiki/One_Definition_Rule

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:18:33 +01:00
Dodji Seketeli
c495a5c5f0 Handle per translation unit and per corpus types maps
Today, whenever a type is added to its scope, a map that associates
the qualified type name to the type is updated.  There is only one
such map in a given ABI corpus.

So whenever a type is looked up from its name, it's that per-corpus
type map that is used.

This setup makes libabigail type lookup be tailored only for binaries
that respect the One Definition Rule of C++[1] (aka ODR) which
basically says that there should be only one type of a given name in
an ABI corpus.

It turns out that many binaries, especically C binaries, don't respect
the ODR.  So a type "struct foo" can be defined in a file a.c and
another *different* type "struct foo" can also be defined in b.c.
What a useful and safe feature! Not.

For those binaries, just having one type map doesn't work.  We need to
have one type map per translation unit, and one map per-corpus map.

This is the strategy implemented by this patch.

With this patch, whenever a type is added to its scope, a
per translation unit type map is updated.  The per corpus map is
updated as well.  If there are more than one type of a given name, the
entry in the per corpus type map for that type is left empty.

Type lookup now potentially becomes a two phases lookup.  Whenever a
type is looked up from its name, the per corpus type map is looked at
first.  If the type is not in that per corpus type map, then the per
translation unit type maps are lookup up, in sequence.

The patch thus re-visits the type maps updating and lookup routines to
adapt them to the new scheme.  The patch also updates the clients of
the type map updating and lookup code.

Note that this patch is part of a series of patches which aims to move
libabigails away from its ODR-centric organization to make it work
well also on binary where the ODR is not relevant.  As such, the patch
doesn't assure that "make check" passes.  To have "make check" pass,
you need to have all the patches of the series applied.

[1]: https://en.wikipedia.org/wiki/One_Definition_Rule

	* include/abg-fwd.h (lookup_type_in_corpus): Remove.  This is to
	be replaced by the new lookup_type below.
	(lookup_{basic, class, union, enum, typedef, qualified, pointer,
	reference, array, function, class_or_typedef,
	class_typedef_or_enum}_type):
	(lookup_class_type_through_scopes, lookup_type)
	(lookup_type_through_scopes, lookup_or_synthesize_fn_type)
	* src/abg-ir-priv.h (struct translation_unit::priv):  Move this
	private type here, from abg-ir.h.
	(synthesize_type_from_translation_unit): Declare new functions.
	* include/abg-ir.h (class type_maps): Define new type.
	(translation_unit::get_function_types): Remove.
	(translation_unit::get_types): Now return a type_maps.
	(translation_unit::get_live_fn_types): Declare new type.
	(class decl_base): Make canonicalize be a friend of this class.
	* src/abg-ir.cc (struct translation_unit::priv): Move this to
	abg-ir-priv.h
	(struct type_maps::priv): Define new type.
	(type_maps::{basic, class, union, enum, typedef, qualified,
	pointer, reference, array, function}_types): Define new accessors.
	(translation_unit::bind_function_type_life_time): Adjust.
	(translation_unit::get_function_types): Remove accessor.
	(translation_unit::get_types, get_live_fn_types): Define new
	accessors.
	(lookup_type_in_translation_unit)
	(lookup_class_type_in_translation_unit)
	(lookup_function_type_in_translation_unit)
	(synthesize_type_from_translation_unit)
	(synthesize_function_type_from_translation_unit)
	(lookup_class_type_in_translation_unit) Remove function
	definitions.
	(lookup_type_in_map): Define function template.
	(lookup_{basic, class, union, typedef, class_or_typedef,
	class_typedef_or_enum, qualified, pointer, reference, array,
	function}_type): Define functions.
	(lookup_function_type, lookup_type_through_scopes)
	(lookup_class_type_through_scopes)
	(lookup_basic_type_through_translation_units)
	(lookup_union_type_through_translation_units)
	(lookup_enum_type_through_translation_units)
	(lookup_class_type_through_translation_units)
	(lookup_typedef_type_through_translation_units)
	(lookup_qualified_type_through_translation_units)
	(lookup_pointer_type_through_translation_units)
	(lookup_reference_type_through_translation_units)
	(lookup_array_type_through_translation_units)
	(lookup_function_type_through_translation_units)
	(lookup_type_through_translation_units)
	(lookup_or_synthesize_fn_type, lookup_type): Likewise.
	(maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Define function
	template, specilizations and functions.
	(synthesize_type_from_translation_unit)
	(synthesize_function_type_from_translation_unit): Define
	functions.
	* include/abg-corpus.h (corpus::get_types): Declare new accessor.
	* src/abg-corpus.cc (corpus::priv::get_types): Define new
	accessor.
	(corpus::get_types): Likewise.
	(lookup_type_in_corpus, lookup_class_type_in_corpus)
	(lookup_type_in_corpus, lookup_function_type_in_corpus)
	(maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Remove.
	(lookup_{basic, class, union, enum, typedef, qualified, pointer,
	reference, array, function, class_or_typedef,
	class_typedef_or_enum}_type): Likewise.
	* src/abg-corpus-priv.h (corpus::priv::{basic, class, union,
	typedef, qualified, pointer, reference, array, function}_types):
	Remove these data members.
	(corpus::priv::get_scopes): Remove member function.
	(corpus::priv::get_{basic, class, union, enum, typedef, qualified,
	pointer, reference, array, function}_types): Remove member
	function declarations.
	(corpus::priv::types_): New data member.
	(corpus::priv::get_types): Declare new member function.
	(lookup_{basic, class, enum, typedef, class_or_typedef, qualified,
	pointer, reference, array, function}_type): Declare new functions.
	* src/abg-dwarf-reader.cc
	(read_context::resolve_declaration_only_classes)
	(build_translation_unit_and_add_to_ir): Adjust use of
	lookup_class_type.
	* src/abg-reader.cc (read_context::type_is_from_translation_unit):
	Adjust to the use of lookup_function_type_in_translation_unit that
	got renamed into lookup_function_type.
	* src/abg-writer.cc (type_ptr_cmp::operator()): New operator
	implementation.
	(read_context::sort_type): Add new overloads.
	(write_translation_unit): Adjust to get the function types from
	the new translation_unit::get_live_fn_types and sort them.
	* tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust
	to use the new lookup_or_synthesize_fn_type, in lieu of
	lookup_function_type_in_corpus.  Adjust to use lookup_type in lieu
	of lookup_type_in_corpus.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:18:33 +01:00
Dodji Seketeli
bca3f9d163 Make abg-fwd.h use *_sptr typedefs
Until now, the abg-fwd.h where the necessary forward generic
declarations where put didn't contain the convenience typedefs of the
form foo_sptr that designate a shared pointer to type foo.

This patch moves these convenience typedefs as well as the missing
forward declarations from abg-ir.h to abg-fwd.h.  The patch also
adjusts the function declarations in abg-fwd.h to make them use these
convenience typedefs.

	* include/abg-ir.h: Move convience typedef declarations and some
	necessary forward declarations to ...
	* include/abg-fwd.h: ... here.
	(is_enum_type, is_var_decl): Take a pointer to type_or_decl_base.
	(lookup_type_in_scope): Return a type_base_sptr.
	(lookup_type_through_scopes): Introduce this to later replace the
	overload of lookup_type_in_translation_unit that takes a list of
	strings.
	(lookup_type_in_scope): Return a type_base_sptr, not a
	decl_base_sptr.
	* src/abg-ir.cc (lookup_type_in_scope, lookup_node_in_scope)
	(lookup_var_decl_in_scope): Adjust.
	(is_enum_type, is_var_decl): Take a pointer to type_or_decl_base.
	(lookup_node_in_scope): Return a type_or_decl_base_sptr.
	(lookup_type_in_scope): Return a type_base_sptr.
	(lookup_node_in_translation_unit): Return a
	type_or_decl_base_sptr.
	(lookup_type_through_scopes): Replace
	lookup_type_in_translation_unit.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:18:32 +01:00
Chenxiong Qi
6167026544 Fix wrong variable name
* tools/fedabipkgdiff: (diff_latest_rpms_based_on_distros): Fix
	wrong variable name distro.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
2016-12-19 12:31:02 +01:00
Chenxiong Qi
a028c1735d Warn properly when cannot find peer RPM
* tools/fedabipkgdiff: (RPMCollection.get_peer_rpm): Return None
	when cannot find peer RPM due to nonexistent arch.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
2016-12-19 12:30:18 +01:00
Chenxiong Qi
f8ca17190b Read Koji config via Koji API
Besides reading Koji config via Koji API read_config, option --topdir is
also renamed to --topurl that is the correct one should be used.

	* tools/fedabipkgdiff: Read DEFAULT_KOJI_TOPURL and
	DEFAULT_KOJI_SERVER from Koji config via Koji API read_config.
	(build_commandline_args_parser): --topdir is renamed to
	--topurl.
	* doc/manuals/fedabipkgdiff.rst: Rename --topdir to --topurl.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
2016-12-19 12:29:22 +01:00
Chenxiong Qi
8ac5e078c5 Follow moved packages when download
This patch makes fedabipkgdiff able to follow the new place to download
packages.

	* tools/fedabipkgdiff: (download_rpm) Add --location to curl
	CLI.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
2016-12-19 12:28:55 +01:00
Chenxiong Qi
0011e5b0b6 More document for local RPMs comparison
* doc/manuals/fedabipkgdiff.rst: Add more document for local RPMs
	comparison. Also fixed a typo.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
2016-12-19 12:03:19 +01:00
Ondrej Oprala
ee00b09f21 Properly report missing files for abipkgdiff
Currently, if abipkgdiff is given a path to a nonexistent file,
it propagates all the way until package classification
and ends up being reported as "PKG should be a valid package file",
which doesn't hint it's not there at all.

        * tools/abipkgdiff.cc: (class options): Add the "nonexistent_file" flag
        (parse_command_line): Check if the files given exist.
        (main): Check the nonexistent_file flag. If any of the input
        files don't exist, report it and exit. Also, for present and future test
        uniformity, only show the base names of the packages when using their
        names in error output.
        * tests/test-diff-pkg.cc: Add a new regression test.
        * tests/data/test-diff-pkg/test-nonexistent-report-0.txt: The
        expected output of the above regression test.
        * tests/data/Makefile.am: Add the above file to the list.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
2016-12-15 20:16:01 +01:00
Dodji Seketeli
6eb35fd54f Misc style cleanup
* src/abg-dwarf-reader.cc (build_function_type): Remove
	unnecessary new line.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-15 16:25:41 +01:00
Dodji Seketeli
7dbe1f7249 make is_anonymous_type work for unions and classes
* src/abg-ir.cc (is_anonymous_type): Make this work for class or
	union types, no only classes.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-15 16:25:41 +01:00
Dodji Seketeli
0b47f8dc67 Naming typedefs of classes are not read properly from abixml
When loading a class from abixml and when that class has a naming
typedef, build_class_decl fails to build the naming typedef from its
ID because it calls read_context::get_type_decl() instead of
read_context::build_or_get_type_decl().

This patch fixes that issue by using
read_context::build_or_get_type_decl rather than
read_context::get_type_decl.

Also, as read_context::build_or_get_type_decl can trigger the creation
of a class (and recursively call build_class_decl), it needs to be
called after the class type being built is marked as work-in-progress
(aka WIP).  So the handling of the naming typedef is moved to after
the class type being built is marked as WIP.

	* src/abg-reader.cc (build_class_decl): Use
	read_context::build_or_get_type_decl rather than
	read_context::get_type_decl to build the naming typedef referred
	to by the class being built.  Move the handling of naming typedefs
	after the class is marked as WIP and keyed.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-15 16:25:41 +01:00
Dodji Seketeli
f7bb9cad09 Don't early-canonicalize function types when reading abixml
When reading from an abixml file, we sometimes canonicalize function
types before the entire abixml file is read.  This can lead to, e.g, a
function type that is not yet fully built being canonicalized too
early and so its canonical type being wrong because it reflects the
state of the function type at canonicalization time -- but then that
state changed later.

This patch fixes that by forcing us to late-canonicalize function
types, just like we do for all aggregate types.

	* src/abg-reader.cc (read_context::maybe_canonicalize_type):
	late-canonicalize function types too.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-15 16:25:41 +01:00
Ondrej Oprala
c7ec20acc9 Check --enable-rpm dependencies more rigorously
If a user has explicitly specified --enable-rpm when running
"configure", it will now fail unless both rpm2cpio and cpio
are present on the system.

        * configure.ac: Check if both rpm2cpio and cpio
        exist on the system. If not, disable the option and fail the
        configuration if --enable-rpm was specified explicitly.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
2016-12-13 20:55:00 +01:00
Ondrej Oprala
744417d396 abipkgdiff doesn't mention --no-default-suppression in help
* tools/abipkgdiff.cc (display_usage): Mention
        --no-default-suppression as one of the options.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
2016-12-13 20:51:42 +01:00
Ondrej Oprala
fda52842d9 Fix a few remarks made by cppcheck
* src/abg-comparison.cc (types_or_decls_equal::operator()): Pass
	arguments by reference.
        (class_diff::ensure_lookup_tables_populated): Expression
        !A || (A && B) can be reduced to !A || B.
	* src/abg-suppression.cc (suppression_matches_type_no_name):
	Likewise.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
2016-12-12 21:24:28 +01:00
Ondrej Oprala
125c0c3c7c Bug 19272 - abipkgdiff doesn't report arch change
Previously, architecture change wasn't included in the incompatible
changes check.

This patch makes corpus_diff::has_incompatible_changes take
architecture change into account.

It turns out corpus_diff::has_net_changes wasn't taking architecture
or soname change into account either.  This patch fixes that as well.

The patch also updates abicompat.cc to make it use
corpus_diff::has_net_changes() and
corpus_diff::has_incompatible_changes(), instead of open-coding these
member functions.

	* src/abg-comparison.cc (corpus_diff::has_incompatible_changes):
	The architecture change into account.
	(corpus_diff::has_net_changes): Take architecture and soname
	changes into account.
	* tools/abicompat.cc (perform_compat_check_in_normal_mode): Use
	corpus_diff::{has_net_changes, has_incompatible_changes}.
	* tests/data/test-diff-pkg/dbus-glib-0.104-3.fc23.armv7hl.rpm: New
	test input.
	* tests/data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64--dbus-glib-0.104-3.fc23.armv7hl-report-0.txt:
	New test reference output.
 	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-pkg.cc (in_out_spec): Compare the new package
	above against an x86_64 one.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-12 19:55:23 +01:00
Chenxiong Qi
783099cd25 Bug 20380 - Compare two local RPMs
Bug 20270 is also fixed.

This patch allows developer to compare two local RPMs in form

    fedabipkgdiff some/place/foo.rpm another/place/bar.rpm

But, network is still needed to talk with Koji.

This patch also introduces new terms for libabigail, that is the
subject, ancillary package, and comparison half. Subject represents a
package that is subject of the ABI comparison, a subject could be a RPM
and maybe it would be a DEB or some other kind of "package". A subject
may have several ancillary packages that are used to compare the
subject.  Generally, a subject may have devel, debuginfo, or both.

	* configure.ac: add dependent mimetype module.
	* doc/manuals/fedabipkgdiff.rst: Update to add document for the
	new use case of comparing two local RPMs.
	* tests/data/Makefile.am: Include new RPMs for tests.
	* tests/data/test-fedabipkgdiff/dbus-glib/dbus-glib-0.100.2-2.fc20.x86_64.rpm:
	New RPM for running test.
	* tests/data/test-fedabipkgdiff/dbus-glib/dbus-glib-0.106-1.fc23.x86_64.rpm:
	Likewise.
	* tests/data/test-fedabipkgdiff/nss-util/nss-util-3.12.6-1.fc14.x86_64.rpm:
	Likewise.
	* tests/data/test-fedabipkgdiff/nss-util/nss-util-3.24.0-2.0.fc25.x86_64.rpm:
	Likewise.
	* tests/data/test-fedabipkgdiff/nss-util/nss-util-devel-3.24.0-2.0.fc25.x86_64.rpm:
	Likewise.
	* tests/data/test-fedabipkgdiff/test4-glib-0.100.2-2.fc20.x86_64.rpm-glib-0.106-1.fc23.x86_64.rpm-report-0.txt:
	Rename filename by adding .rpm extension.
	* tests/data/test-fedabipkgdiff/test5-same-dir-dbus-glib-0.100.2-2.fc20.x86_64--dbus-glib-0.106-1.fc23.x86_64-report-0.txt:
	New reference output for testing comparing local RPMs.
	* tests/data/test-fedabipkgdiff/test6-missing-devel-debuginfo-nss-util-3.12.6-1.fc14.x86_64--nss-util-3.24.0-2.0.fc25.x86_64-report-0.txt:
	New reference output for testing comparison without non-existent
	debuginfo or development package.
	* tests/runtestfedabipkgdiff.py.in (FEDABIPKGDIFF_TEST_SPECS):
	Rename filename for test4. Add two new test cases.
	(run_fedabipkgdiff_tests): Remove semicolon and trailing
	whitespaces.
	(main): Likewise.
	(ensure_output_dir_created): Likewise.
	* tools/fedabipkgdiff: Require some new modules.
	Fix of return code.
	(PkgInfo): Renamed to ComparisonHalf.
	(match_nvr): New method to determine if a string matches format
	of N-V-R.
	(match_nvra): New method to determine if a string matches format
	of N-V-R.A.
	(is_rpm_file): New method to guess if a file is a RPM file.
	(RPM.is_peer): New method to determine if current RPM is a peer
	of another.
	(RPM.filename): Use Koji module API to construct the filename.
	(RPM.nvra): Get nvra from filename instead of constructing
	manually that is duplicated with Koji module API.
	(RPMCollection): New class to represent a set of RPMs.
	(generate_pkg_info_pair_for_abipkgdiff): New method working as a
	generator to yeild comparison halves for running abipkgdiff.
	(Brew.getRPM): Fix string format with incorrect argument.
	(Brew.select_rpms_from_a_build): Return instance of
	RPMCollection.
	(abipkgdiff): If there is no debuginfo or development package,
	just ignore it and leave a warning. If --error-on-warning is
	specified, raise an exception instead. Arguments are modified
	to represent the new name ComparisonHalf, and relative docstring
	is also updated.
	(magic_construct): Removed.
	(run_abipkgdiff): Rewrite.
	(make_rpms_usable_for_abipkgdiff): Removed.
	(diff_local_rpm_with_latest_rpm_from_koji): Rewrite by using
	RPMCollection.
	(diff_latest_rpms_based_on_distros): Likewise.
	(diff_two_nvras_from_koji): Likewise.
	(diff_from_two_rpm_files): New method to compare two local RPMs.
	(build_commandline_args_parser): Add new option
	--error-on-warning.
	(main): Add support to compare local RPMs.

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-12 15:21:10 +01:00
Dodji Seketeli
85318068cd Fix template_decl:#️⃣:operator()
While hashing template_decl we inadvertently forget the contribution
of the name of the type to the hash.

This was spotted by Ondrej Oprala.

Fixed thus.

	* src/abg-hash.cc (template_decl:#️⃣:operator()): Combine the
	contribution of the qualified name to the contribution of the type
	name to the hash.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-12 12:14:21 +01:00
Dodji Seketeli
d7faae38f6 Fix aborting when reading .foo symbols from a ppc64 binary
On ppc64, the value of a function symbol is *usually* the pointer to
the function.  That function pointer value refers to an index inside
the ".opd" (Official Procedure Descriptor) section.  That section is a
record of tripplets values.  One of these values is the address of the
entry point of the function.  A debug information entry for a
function, in DWARF, refers to the entry point of the function; not to
the function pointer address.

So libabigail builds a table that associates a function entry point
address to its function pointer address.

So, if a function is named "foo", it has an entry in the symbol table
for the symbol name "foo"; the value of that symbol is the function
pointer address of foo, which refers to an offset in the ".opd"
section.

But then it turns out that there is also going to be an entry in the
symbol table for an artificial symbol named ".foo".  Pleast note the
dot before the suffix "foo".  The value of the ".foo" symbol is the
address of the entry point of the function "foo"; it's an address in
the ".text" section this time.

Libabigail's ELF symbols reading code was (wrongly) expecting all
entries in the symbol table that refer to function to have values that
are offset in the ".opd" section.  It wasn't expecting the ".foo"
symbols whose value are an address in the ".text" section.

This patch fixes the ELF symbol reading code to make it be aware of
the ".foo" symbols too.

	* abg-dwarf-reader.cc (read_context::find_opd_section): Fix
	comment.
	(read_context::load_symbol_maps): If for a given function entry
	point (that we got by looking at the ".opd" section for a given
	function pointer value) we already had an entry in the
	function_entry_address -> symbol, maybe it means that the previous
	entry that we had was from an entry in the symbol table which
	value was directly the entry point address of a function.  In that
	case, if the name of the symbol is "foo", the name of the symbol
	which value is directly the entry point address is ".foo".  What
	we do in this case is that we just keep the reference to the "foo"
	symbol in the function_entry_address -> symbol map.
	(read_context::address_is_in_opd_section): Define new member
	function.
	* tests/data/test-diff-pkg/gmp-4.3.1-10.el6.ppc64.rpm: New test input.
	* tests/data/test-diff-pkg/gmp-4.3.1-7.el6_2.2.ppc64.rpm: Likewise.
	* tests/data/test-diff-pkg/gmp-debuginfo-4.3.1-10.el6.ppc64.rpm: Likewise.
	* tests/data/test-diff-pkg/gmp-debuginfo-4.3.1-7.el6_2.2.ppc64.rpm: Likewise.
	* tests/data/test-diff-pkg/gmp-4.3.1-7.el6_2.2.ppc64--gmp-4.3.1-10.el6.ppc64-report-0.txt:
	New test reference output.
	* tests/data/Makefile.am: Add the new test input and reference
	output to source distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Add the new test inputs
	and reference output to the set of inputs that are compared.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-09 01:07:05 +01:00
Dodji Seketeli
985397a47a Bug 20927 - Segfault when $HOME is not set
When comparing two binaries with abi{pkg}diff, if $HOME is not set, we
segfault at some places because we don't expect that.  I ran "make
check" after doing "unset HOME" to help me catch most of those places.
This patch updates the code to handle that case.

	* src/abg-tools-utils.cc
          (get_default_user_suppression_file_path): Handle the case where
	the HOME environment variable is not set.
	* tools/abipkgdiff.cc (package::extracted_packages_parent_dir):
	Likewise.  When $HOME is empty set then use $TMPDIR.  If it's
	empty too then use "/tmp".

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-05 10:21:13 +01:00
Dodji Seketeli
5ed0e40bfd Bug 20887 - Show relative change of offsets
Until now, an offset change is reported by showing the old and new
offsets of the data member that changed.

This patch adds the string "(by +N bits)" with 'N' being the number of
bits by which the offset of the data member was increased, or "(by -N
bits) if the offset of the data member was decreased of N bits.

The patch also emits a string that says "size hasn't changed" if the
size of the structure did not change.

This can be disabled by a new --no-show-relative-offset-changes
option.

	* doc/manuals/abidiff.rst: Document the new
	--no-show-relative-offset-changes.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* include/abg-comparison.h
	(diff_context::show_relative_offset_changes): New accessors.
	* include/abg-ir.h ({set,get}_data_member_offset): Return uint64_t
	instead of the less portable size_t.
	* src/abg-comparison.cc
	(diff_context::priv::show_relative_offset_changes_): New data
	member.
	(dif_context::show_relative_offset_changes): Define accessor.
	(maybe_show_relative_offset_change): Define new function.
	(represent): In the overload for var_diff, call the new
	maybe_show_relative_offset_change.
	(report_size_and_alignment_changes):  If the size of the type
	didn't change then say it now.
	* src/abg-ir.cc (set_data_member_offset, get_data_member_offset):
	Take or return a uint64_t instead of a size_t.
	* tools/abidiff.cc (options::show_relative_offset_changes): New
	data member.
	(options::options): Initialize it.
	(display_usage): Display help string for the new
	--no-show-relative-offset-changes.
	(parse_command_line): Parse the new
	--no-show-relative-offset-changes options.
	(set_diff_context_from_opts): Set the
	"show-relative-offset-changes" flag according to the new option.n
	* tools/abipkgdiff.cc (options::show_relative_offset_changes): New
	data member.
	(options::options): Initialize it.
	(display_usage): Add help string for the new
	--no-show-relative-offset-changes option.
	(set_diff_context_from_opts): Set the
	"show-relative-offset-changes" flag according to the new option.
	(parse_command_line): Parse the new command line option.
	* tests/data/test-diff-dwarf/test40-report-0.txt: Add new
	reference output.
	* tests/data/test-diff-dwarf/test40-v0.c: Source code of the first
	test binary.
	* tests/data/test-diff-dwarf/test40-v1.c: Source code of the
	second test binay.
	* tests/data/test-diff-dwarf/libtest40-v0.so: New first test binary.
	* tests/data/test-diff-dwarf/libtest40-v1.so: New second test binary.
	* tests/test-diff-dwarf.cc (in_out_spec): Add the new test
	binaries above to the set of binaries that are compared.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/data/test-abicompat/test7-fn-changed-report-0.txt: Adjust.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Likewise.
	* tests/data/test-abidiff/test-enum0-report.txt: Likewise.
	* tests/data/test-abidiff/test-enum1-report.txt: Likewise.
	* tests/data/test-abidiff/test-struct1-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test0-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test1-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test10-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test11-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test13-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test15-enum-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test27-local-base-diff-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test32-fnptr-changes-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test33-fnref-changes-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test4-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test5-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test6-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test8-report.txt: Likewise.
	* tests/data/test-diff-filter/test0-report.txt: Likewise.
	* tests/data/test-diff-filter/test01-report.txt: Likewise.
	* tests/data/test-diff-filter/test1-report.txt: Likewise.
	* tests/data/test-diff-filter/test13-report.txt: Likewise.
	* tests/data/test-diff-filter/test16-report-2.txt: Likewise.
	* tests/data/test-diff-filter/test16-report.txt: Likewise.
	* tests/data/test-diff-filter/test17-0-report.txt: Likewise.
	* tests/data/test-diff-filter/test17-1-report.txt: Likewise.
	* tests/data/test-diff-filter/test18-report.txt: Likewise.
	* tests/data/test-diff-filter/test19-enum-report-1.txt: Likewise.
	* tests/data/test-diff-filter/test2-report.txt: Likewise.
	* tests/data/test-diff-filter/test23-redundant-fn-parm-change-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test24-compatible-vars-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test25-cyclic-type-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test25-cyclic-type-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test26-qualified-redundant-node-report-0.t:
	Likewise.xt
	* tests/data/test-diff-filter/test26-qualified-redundant-node-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-2.txt:
	Likewise.
	* tests/data/test-diff-filter/test29-finer-redundancy-marking-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test3-report.txt: Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt:
	Likewise.
	* 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: Likewise.
	* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-5.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-7.txt: Likewise.
	* tests/data/test-diff-suppr/test1-typedef-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test1-typedef-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test10-changed-parm-c-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test2-struct-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test23-alias-filter-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test23-alias-filter-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test30-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test4-local-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test4-local-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-5.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-0-1.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-7.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-8.txt: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-02 21:29:28 +01:00
Dodji Seketeli
4f9d682d0b Rename tests/update-test-read-dwarf-output.py
Renamed tests/update-test-read-dwarf-output.py into
tests/update-test-output.py as it can be used for all tests that emit
an output and compare it against a reference output.

	* tests/update-test-output.py: renamed
	tests/update-test-read-dwarf-output.py into this.  Update its
	comments.  Make this script executable.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-02 12:59:32 +01:00
Dodji Seketeli
b4fc841a73 Add tests/data/test-diff-suppr/test33-report-0.txt to tarball
I forgot to add the file testing file
tests/data/test-diff-suppr/test33-report-0.txt to
tests/data/Makefile.am.  This makes the test runtestdiffsupp fail
under 'make distcheck'.

Fixed thus.

	* tests/data/Makefile.am: Add test-diff-suppr/test33-report-0.txt.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-30 11:01:38 +01:00