2014-03-21 14:15:02 +00:00
|
|
|
// -*- Mode: C++ -*-
|
|
|
|
//
|
2015-01-07 12:53:58 +00:00
|
|
|
// Copyright (C) 2013-2015 Red Hat, Inc.
|
2014-03-21 14:15:02 +00:00
|
|
|
//
|
|
|
|
// This file is part of the GNU Application Binary Interface Generic
|
|
|
|
// Analysis and Instrumentation Library (libabigail). This library is
|
|
|
|
// free software; you can redistribute it and/or modify it under the
|
|
|
|
// terms of the GNU Lesser General Public License as published by the
|
|
|
|
// Free Software Foundation; either version 3, or (at your option) any
|
|
|
|
// later version.
|
|
|
|
|
|
|
|
// This library is distributed in the hope that it will be useful, but
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// General Lesser Public License for more details.
|
|
|
|
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this program; see the file COPYING-LGPLV3. If
|
|
|
|
// not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
// Author: Dodji Seketeli
|
|
|
|
|
|
|
|
/// @file
|
|
|
|
///
|
|
|
|
/// This program runs a diff between input dwarf files and compares
|
|
|
|
/// the resulting report with a reference report. If the resulting
|
|
|
|
/// report is different from the reference report, the test has
|
2014-03-29 08:05:21 +00:00
|
|
|
/// failed. Note that the comparison is done using the libabigail
|
|
|
|
/// library directly.
|
2014-03-21 14:15:02 +00:00
|
|
|
///
|
|
|
|
/// The set of input files and reference reports to consider should be
|
|
|
|
/// present in the source distribution.
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <fstream>
|
|
|
|
#include <iostream>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include "abg-tools-utils.h"
|
|
|
|
#include "test-utils.h"
|
|
|
|
#include "abg-dwarf-reader.h"
|
|
|
|
#include "abg-comparison.h"
|
|
|
|
|
|
|
|
using std::string;
|
|
|
|
using std::ofstream;
|
|
|
|
using std::cerr;
|
|
|
|
|
|
|
|
/// This is an aggregate that specifies where a test shall get its
|
2014-03-29 08:05:21 +00:00
|
|
|
/// input from and where it shall write its ouput to.
|
2014-03-21 14:15:02 +00:00
|
|
|
struct InOutSpec
|
|
|
|
{
|
|
|
|
const char* in_elfv0_path;
|
|
|
|
const char* in_elfv1_path;
|
|
|
|
const char* in_report_path;
|
|
|
|
const char* out_report_path;
|
|
|
|
};// end struct InOutSpec
|
|
|
|
|
|
|
|
InOutSpec in_out_specs[] =
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test0-v0.o",
|
|
|
|
"data/test-diff-dwarf/test0-v1.o",
|
|
|
|
"data/test-diff-dwarf/test0-report.txt",
|
|
|
|
"output/test-diff-dwarf/test0-report.txt"
|
|
|
|
},
|
2014-03-29 08:04:01 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test1-v0.o",
|
|
|
|
"data/test-diff-dwarf/test1-v1.o",
|
|
|
|
"data/test-diff-dwarf/test1-report.txt",
|
|
|
|
"output/test-diff-dwarf/test1-report.txt"
|
|
|
|
},
|
2014-04-01 10:38:51 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test2-v0.o",
|
|
|
|
"data/test-diff-dwarf/test2-v1.o",
|
|
|
|
"data/test-diff-dwarf/test2-report.txt",
|
|
|
|
"output/test-diff-dwarf/test2-report.txt"
|
|
|
|
},
|
2014-04-04 09:39:41 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test3-v0.o",
|
|
|
|
"data/test-diff-dwarf/test3-v1.o",
|
|
|
|
"data/test-diff-dwarf/test3-report.txt",
|
|
|
|
"output/test-diff-dwarf/test3-report.txt"
|
|
|
|
},
|
2014-04-05 10:40:28 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test3-v0.o",
|
|
|
|
"data/test-diff-dwarf/test3-v1.o",
|
|
|
|
"data/test-diff-dwarf/test3-report.txt",
|
|
|
|
"output/test-diff-dwarf/test3-report.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test4-v0.o",
|
|
|
|
"data/test-diff-dwarf/test4-v1.o",
|
|
|
|
"data/test-diff-dwarf/test4-report.txt",
|
|
|
|
"output/test-diff-dwarf/test4-report.txt"
|
|
|
|
},
|
2014-04-11 14:52:00 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test5-v0.o",
|
|
|
|
"data/test-diff-dwarf/test5-v1.o",
|
|
|
|
"data/test-diff-dwarf/test5-report.txt",
|
|
|
|
"output/test-diff-dwarf/test5-report.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test6-v0.o",
|
|
|
|
"data/test-diff-dwarf/test6-v1.o",
|
|
|
|
"data/test-diff-dwarf/test6-report.txt",
|
|
|
|
"output/test-diff-dwarf/test6-report.txt"
|
|
|
|
},
|
2014-04-16 15:14:48 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test7-v0.o",
|
|
|
|
"data/test-diff-dwarf/test7-v1.o",
|
|
|
|
"data/test-diff-dwarf/test7-report.txt",
|
2014-04-17 13:26:38 +00:00
|
|
|
"output/test-diff-dwarf/test7-report.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test8-v0.o",
|
|
|
|
"data/test-diff-dwarf/test8-v1.o",
|
|
|
|
"data/test-diff-dwarf/test8-report.txt",
|
|
|
|
"output/test-diff-dwarf/test8-report.txt"
|
2014-04-16 15:14:48 +00:00
|
|
|
},
|
2014-08-19 09:08:36 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/libtest9-v0.so",
|
|
|
|
"data/test-diff-dwarf/libtest9-v1.so",
|
|
|
|
"data/test-diff-dwarf/test9-report.txt",
|
|
|
|
"output/test-diff-dwarf/test9-report.txt"
|
|
|
|
},
|
Support C and C++ array type.
* include/abg-comparison.h (array_diff): Declare new class.
(array_diff_sptr): Shared pointer to type array_diff.
(compute_diff): Overload the function to take type
array_diff_sptr as the first two arguments.
* include/abg-fwd.h (array_type_def): Declare new class.
(subrange_type): Likewise.
(is_array_def): Declare new function.
* include/abg-ir.h (array_type_def_sptr): Shared pointer
to type array_type_def.
(array_type_def): Declare new class.
(ir_node_visitor::visit): Declare a new virtual function
taking a pointer to type array_type_def as an argument.
* src/abg-comparison.cc (compute_diff_for_types): Add
try_to_diff for two instances of type array_type_def.
(array_diff::priv): declare struct for holding private members
of type array_diff.
(array_diff::array_diff): Define constructor.
(array_diff::{first,second}_array):Define new
member functions.
(array_diff::element_type_diff): Likewise.
(array_diff::{length,report,traverse}): Likewise.
(compute_diff): Define function overloaded in
include/abg-comparison.h.
* src/abg-dwarf-reader.cc (build_array_type): Define new
function. Handle DW_TAG_array_type and DW_TAG_subrange type.
(build_ir_node_from_die): Amend case DW_TAG_array_type with
a call to build_array_type.
* src/abg-hash.cc (array_type_def::hash): Declare new struct.
(type_base::dynamic_hash::operator()): Attempt to dynamic_cast
the argument to type array_type_def as well.
(array_type_def::hash): Declare new struct.
* src/abg-ir.cc (array_type_def::array_type_def): Define
constructors.
(array_type_def::priv): declare struct for holding private members
of type array_type_def.
(array_type_def::operator==(const decl_base&):
Define new operator.
(array_type_def::operator==(const type_base&):
Likewise.
(array_type_def::append_subrange{,s}): Define
new functions.
(array_type_def::{set,get}_size_in_bits): Likewise.
(array_type_def::get_dimension_count): Likewise.
(array_type_def::get_qualified_name): Likewise.
(array_type_def::get_pretty_representation): Likewise.
(array_type_def::get_subrange_representation): Likewise.
(array_type_def::traverse): Likewise.
(array_type_def::get_{element_type,location,subranges}): Likewise.
(array_type_def::is_infinite): Likewise.
(array_type_def::~array_type_def): Define destructor.
(ir_node_visitor::visit): Define function, taking
pointer to array_type_def as an argument.
* src/abg-reader.cc (map_id_and_node): Check if node
is an array.
(is_array_def): Check if object is an array.
(handle_element_node): Handle array_type_def as well.
(build_subrange_type): Define new function.
(build_array_type_def): Likewise.
(build_type): Build type array_type_def as well.
(build_type_composition): Likewise.
(handle_array_type_def): Define new function.
* src/abg-writer.cc: (write_decl): Output arrays
as well.
(write_member_type): Likewise.
(write_type_composition): Likewise.
(write_array_type_def): Define new function.
* tests/data/test-diff-dwarf/test{10,11}-v{0,1}.{cc,o}: New test source
files
* tests/data/test-diff-dwarf/test{10,11}-report.txt: Likewise.
* tests/data/test-diff-dwarf/test10-report.txt: New test input.
* tests/data/test-read-dwarf/test7.cc: New test source
file.
* tests/data/test-read-dwarf/test7.so: New input binary
to read.
* tests/data/test-read-dwarf/test7.so.abi: New reference
test to compare against.
* tests/data/test-read-write/test25.xml: New test source
file.
* tests/test-diff-dwarf.cc: Adjust to launch the new test.
* tests/test-read-dwarf.cc: Likewise.
* tests/test-read-write.cc: Likewise.
* test/Makefile.am: Add the new test inputs to the source
distribution.
Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-08-18 09:56:43 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test10-v0.o",
|
|
|
|
"data/test-diff-dwarf/test10-v1.o",
|
|
|
|
"data/test-diff-dwarf/test10-report.txt",
|
|
|
|
"output/test-diff-dwarf/test10-report.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test11-v0.o",
|
|
|
|
"data/test-diff-dwarf/test11-v1.o",
|
|
|
|
"data/test-diff-dwarf/test11-report.txt",
|
|
|
|
"output/test-diff-dwarf/test11-report.txt"
|
|
|
|
},
|
2014-08-25 21:06:18 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/libtest12-v0.so",
|
|
|
|
"data/test-diff-dwarf/libtest12-v1.so",
|
|
|
|
"data/test-diff-dwarf/test12-report.txt",
|
|
|
|
"output/test-diff-dwarf/test12-report.txt"
|
|
|
|
},
|
2014-09-03 06:46:58 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test13-v0.o",
|
|
|
|
"data/test-diff-dwarf/test13-v1.o",
|
|
|
|
"data/test-diff-dwarf/test13-report.txt",
|
|
|
|
"output/test-diff-dwarf/test13-report.txt"
|
|
|
|
},
|
2014-09-16 12:53:30 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test14-inline-v0.o",
|
|
|
|
"data/test-diff-dwarf/test14-inline-v1.o",
|
|
|
|
"data/test-diff-dwarf/test14-inline-report.txt",
|
|
|
|
"output/test-diff-dwarf/test14-inline-report.txt"
|
|
|
|
},
|
2014-09-16 11:40:35 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test15-enum-v0.o",
|
|
|
|
"data/test-diff-dwarf/test15-enum-v1.o",
|
|
|
|
"data/test-diff-dwarf/test15-enum-report.txt",
|
|
|
|
"output/test-diff-dwarf/test15-enum-report.txt"
|
|
|
|
},
|
Support comparing symbols not referenced by debug info
* doc/manuals/abidiff.rst: Adjust intro to mention that w/o debug
info, abidiff now works but just report about added/removed
symbols. Add documentation about the new
--no-unreferenced-symbols option.
* include/abg-comparison.h (string_elf_symbol_map): New typedef.
(diff_context::show_symbols_unreferenced_by_debug_info): Declare
new accessors.
* src/abg-comparison.cc
(diff_context::priv::show_syms_unreferenced_by_di_): New data
member.
(diff_context::priv::priv): Adjust.
(diff_context::show_symbols_unreferenced_by_debug_info): Implement
these accessors.
(corpus_diff::priv::{unrefed_fn_syms_edit_script_,
unrefed_var_syms_edit_script_, added_unrefed_fn_syms_,
deleted_unrefed_fn_syms_, added_unrefed_var_syms_,
deleted_unrefed_var_syms_}): New data members.
(corpus_diff::priv::diff_stats::{num_func_syms_removed,
num_func_syms_added, num_var_syms_removed, num_var_syms_added}):
New data members.
(corpus_diff::priv::diff_stats::diff_stats): Adjust.
(corpus_diff::ensure_lookup_tables_populated): Populate lookup
tables for added/removed symbols that are not referenced by any
debug info.
(corpus_diff::priv::apply_filters_and_compute_diff_stats): Compute
stats for the added/removed symbols not referenced by any debug
info.
(corpus_diff::priv::emit_diff_stats): Emit stats about
added/removed symbols that are not referenced by any debug info.
(corpus_diff::length): Adjust to take in account added/removed
symbols not referenced by any debug info.
(show_linkage_name_and_aliases): New static function.
(corpus_diff::report): When emitting a symbol name, emit its
version too, and tell if it aliases other symbols. Avoid emitted
extra new lines. Report added/removed symbols not referenced by
any debug info.
(compute_diff): In the overload for corpus_sptr, compute the diffs
for symbols not referenced by debug info.
* include/abg-corpus.h
(corpus::get_unreferenced_{function,variable}_symbols): Declare
new member functions.
* src/abg-corpus.cc (corpus_priv::{unrefed_fun_symbols,
unrefed_var_symbols}): New data members.
(corpus_priv::build_unreferenced_symbols_tables): Define new
member function.
(struct comp_elf_symbols_functor): New functor.
(corpus::is_empty): Adjust to take in account added/removed
symbols not referenced by debug info.
(corpus::{get_unreferenced_function_symbols,
corpus::get_unreferenced_variable_symbols}): Define these
accessors.
* include/abg-dwarf-reader.h (enum status): Transform this into
bitfields. Add a STATUS_UNKNOWN value that has the value 0.
(operator|(status, status), operator&(status, status))
(operator|=(status&, status), operator&=(status, status)): New
bit-wise operators to manipulate instances of the status bit-field.
* src/abg-dwarf-reader.cc (get_version_for_symbol): Fix this to
avoid returning garbage version sometimes.
(read_debug_info_into_corpus): Fix this to return a non-null but
empty corpus_sptr when there is no debug info available.
(operator|(status, status), operator&(status, status))
(operator|=(status&, status), operator&=(status, status)): Define
these new bitwise operators to manipulate instances of the status
bit-field.
(read_corpus_from_elf): Now that the abigail::dwarf_reader::status
is a bit-field, set it to reflect if debug info and/or symbol
tables have been found. Do not bail out if debug info hasn't been
found. Rather, keep going, and go look for symbols-only; this is
a kind of operating in degraded mode.
* include/abg-ir.h (elf_symbol::get_aliases_id_string): Add a flag
that says if the current instance of elf_symbol should be included
in the list of aliases or not.
* src/abg-ir.cc (elf_symbol::get_aliases_id_string): Define it.
* tests/data/test-diff-dwarf/test16-syms-only-v{0,1}.o: New test
input.
* tools/abidiff.cc
(options::show_symbols_not_referenced_by_debug_info): New data
member.
(options:options): Adjust.
(display_usage): Add an info string for the new
--no-unreferenced-symbols command line option.
(parse_command_line): Parse the new --no-unreferenced-symbols
command line.
(set_diff_context_from_opts): Set the diff_context according to
the presence of --no-unreferenced-symbols.
(main): Adjust for the fact that abigail::dwarf_reader::status is
now a bit-field.
* tools/abilint.cc (main): Adjust for the fact that
abigail::dwarf_reader::status is now a bit-field..
():
* tests/data/test-diff-dwarf/test16-syms-only-report.txt: New test
reference output.
* tests/data/test-diff-dwarf/test16-syms-only-v{0,1}.cc: Source code
for new test input.
* tests/data/test-diff-dwarf/test17-non-refed-syms-v{0,1}.o: New
test input.
* tests/data/test-diff-dwarf/test17-non-refed-syms-v{0,1}.cc: New
source code for test input.
* tests/data/test-diff-dwarf/libtest18-alias-sym-v{0,1}.so: New
test input.
* tests/data/test-diff-dwarf/test18-alias-sym-report-0.txt:
Reference output for new test input.
* tests/data/test-diff-dwarf/test18-alias-sym-v{0,1}.cc: Source
code for new test input.
* tests/data/test-diff-dwarf/test18-alias-sym-version-script:
Source code for new test input.
* tests/Makefile.am: Add the new test materials to the source
distribution.
* tests/test-diff-dwarf.cc(in_out_specs): Add the new input tests
above to the array of tests to run by this harness.
(main): Emit empty reports for empty resulting diffs.
* tests/data/test-diff-dwarf/test{0,8,9,12,14-inline-report,}-report.txt:
Adjust.
* tests/data/test-diff-filter/test{0,01,2,4,5,7,8,9,10,12,13,15-0,15-1}-report.txt:
Likewise.
* tests/data/test-diff-filter/test{19-enum,20-inline,}-report-0.txt:
Likewise.
* tests/data/test-diff-suppr/test0-type-suppr-report-{1,2}.txt:
Likewise.
* tests/data/test-diff-suppr/test{1,2}-typedef-suppr-report-1.txt:
Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-22 16:05:31 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test16-syms-only-v0.o",
|
|
|
|
"data/test-diff-dwarf/test16-syms-only-v1.o",
|
|
|
|
"data/test-diff-dwarf/test16-syms-only-report.txt",
|
|
|
|
"output/test-diff-dwarf/test16-syms-only-report.txt"
|
|
|
|
},
|
2014-12-07 22:34:21 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test17-non-refed-syms-v0.o",
|
|
|
|
"data/test-diff-dwarf/test17-non-refed-syms-v1.o",
|
|
|
|
"data/test-diff-dwarf/test17-non-refed-syms-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test17-non-refed-syms-report-0.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/libtest18-alias-sym-v0.so",
|
|
|
|
"data/test-diff-dwarf/libtest18-alias-sym-v1.so",
|
|
|
|
"data/test-diff-dwarf/test18-alias-sym-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test18-alias-sym-report-0.txt"
|
|
|
|
},
|
Support reading and comparing soname from ELF files
Libabigail's DWARF reader doesn't read the DT_SONAME tag from the
.dynamic section. The abigail::corpus type doesn't have a property
for that tag either. And the comparison engine doesn't take that tag
in when comparing corpora.
This patch modifies the DWARF reader to read the DT_SONAME and
DT_NEEDED tags from the .dynamic section. The value of DT_SONAME tag
is then saved in the new corpus property accessed by the new
abigail::corpus::get_soname() accessor. The comparison engine has
also been modified to compare the sonames of two corpora being
compared. Note that the value of the DT_NEEDED elf tag is saved in a
new corpus property that is accessed via the new
abigail::corpus::get_needed() getter. This property is not used yet.
This patch also adds a unit test for this new feature.
* include/abg-corpus.h (corpus::{get_needed, set_needed,
get_soname, set_soname}): Declare new accessors.
* src/abg-corpus.cc (corpus::priv::{needed, soname}): New data
members.
(corpus::{get_needed, set_needed, get_soname, set_soname}): Define
new accessors.
(corpus::is_empty): Take dt_needed and dt_soname in account in
computing empty-ness.
* src/abg-dwarf-reader.cc (read_context::{dt_needed_,
dt_soname_}): New data members.
(read_context::{dt_needed, dt_soname}): New accessors.
(read_context::load_dt_soname_and_needed): New member function.
(read_corpus_from_elf): Call the new
read_context::load_dt_soname_and_needed() to read the dt_soname
and dt_needed tags. Set them to the corpus.
* include/abg-comparison.h (diff_context::show_soname_change):
Declare new accessors.
* src/abg-comparison.cc (diff_context::priv::show_soname_change_):
New data member.
(diff_context::priv::priv): Initialize the new data member
diff_context::priv::show_soname_change_.
(diff_context::show_soname_change): Define new accessors.
(corpus_diff::priv::sonames_equal_): New data member.
(corpus_diff::priv::priv): Initialize the new data member
corpus_diff::priv::sonames_equal_.
(corpus_diff::length): Take the new priv_->sonames_equals_ data
member in account.
(corpus_diff::{report, priv::emit_diff_stats}): If the sonames
changed and we are allowed to report it, then report it.
(compute_diff): In the variant for corpus_diff, do not forget to
compare the sonames.
* src/abg-reader.cc (build_needed, read_elf_needed_from_input):
Define new static functions.
(read_corpus_from_input): Read the 'soname' attribute from the
'abi-corpus' xml element node.
* src/abg-writer.cc (write_elf_needed): Define new static
function.
(write_corpus_to_native_xml): Write a new 'elf-needed' xml element
node that contains one xml 'dependency' element node per
dependency to emit. This uses the new write_elf_needed() function
above.
* tests/data/test-diff-dwarf/libtest19-soname-v0.so: New test
input data.
* tests/data/test-diff-dwarf/libtest19-soname-v1.so: Likewise.
* tests/data/test-diff-dwarf/test19-soname-report-0.txt: Likewise.
* tests/data/test-diff-dwarf/test19-soname-v0.c: Source code of
the first binary above.
* tests/data/test-diff-dwarf/test19-soname-v1.c: Source code of
the second binary above.
* tests/test-diff-dwarf.cc (in_out_specs): Add the test input
above to the list of test input to run this harness on.
* tests/data/Makefile.am: Add the new test input data above.
* tests/data/test-read-dwarf/test{0,1}.abi: Adjust.
* tests/data/test-read-dwarf/test{2,3,4,6,}.so.abi: Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-07 20:01:20 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/libtest19-soname-v0.so",
|
|
|
|
"data/test-diff-dwarf/libtest19-soname-v1.so",
|
|
|
|
"data/test-diff-dwarf/test19-soname-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test19-soname-report-0.txt"
|
|
|
|
},
|
2014-12-09 11:37:23 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/libtest20-add-fn-parm-v0.so",
|
|
|
|
"data/test-diff-dwarf/libtest20-add-fn-parm-v1.so",
|
|
|
|
"data/test-diff-dwarf/test20-add-fn-parm-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test20-add-fn-parm-report-0.txt"
|
|
|
|
},
|
Un-share diff nodes in the comparison IR
Until now, the diff nodes of the comparison IR were shared. That is,
two diffs about the same subjects were represented by the same diff
node that would appear twice in the tree.
This was preventing us from spotting e.g, the first occurrence of a
diff node that would later (in the tree) turn to be redundant because
all redundant diff nodes are represented by the same diff node
pointer.
This patch now makes each diff node be different, as far of pointer
comparison is concerned. But it introduces the concept of canonical
diff node to ease the comparison between two diff nodes. Two diff
nodes that are equal have the same canonical diff node.
With this facility, it's now possible to tell the difference between
diff nodes that are (structurally) equal. It's not possible to say
things like "this is the first or second occurrence of the redundant
diff node foo'.
* include/abg-ir.h: Prefix the doc string with "///", rather than
writing it inside a /**/ comment.
* include/abg-comparison.h (function_decl_diff)
(function_decl_diff_sptr, fn_parm_diff, fn_parm_diff_sptr)
(var_diff_sptr, base_diff, class_diff, class_diff_sptr): Move
these class & typedef decls to the top of the file.
(string_changed_base_map, string_changed_parm_map)
(unsigned_changed_parm_map, changed_function_ptr)
(string_changed_function_ptr_map): Remove these typedefs.
(string_base_diff_sptr_map, string_fn_parm_diff_sptr_map)
(unsigned_fn_parm_diff_sptr_map, string_var_diff_sptr_map)
(unsigned_var_diff_sptr_map, string_function_decl_diff_sptr_map)
(string_var_diff_ptr_map): New typedefs.
(diff_context::{has_diff_for,add_diff}): Make these member
functions private.
(diff_context::{set_canonical_diff_for,
set_or_get_canonical_diff_for}): Declare new private member
functions.
(diff_context::{get_canonical_diff_for,
initialize_canonical_diff}): New public member functions.
(diff_context::maybe_apply_filters): Set the default value of the
'traverse_nodes_once' parameter to false.
(compute_diff): Make the overload for class_decl_sptr friend of
the diff_context class.
(class diff): Make the diff_context class a friend of this one.
(diff::set_canonical_diff): Declare new private member function.
(diff::get_canonical_diff): Declare new public member function.
(diff::children_nodes): Make this return a vector<diff_sptr>, rather
than a vector<diff*>.
(diff::append_child_node): Make this take a diff_sptr rather than
a diff*.
(class fn_parm_diff): Declare new type.
(compute_diff): Declare new overload for the new
function_decl::parameter_sptr.
(function_decl_diff::subtype_changed_parms): Return a
string_fn_parm_diff_sptr_map rather than a string_changed_parm.
(function_decl_diff::children_nodes): Return a vector<diff_sptr>.
(function_decl_diff::append_child_node): Take a diff_sptr.
(function_decl_diff::changed_functions): Return a
string_function_decl_diff_sptr_map.
(function_decl_diff::changed_variables): Return a
string_var_diff_sptr.
(class function_decl::parameter): Make this a pimpled class.
Also, make it inherit decl_base.
(equals): New overload for function_decl::parameter.
(struct function_decl::parameter::hash): Declare this.
(ir_node_visitor::visit): Declare new overload for
function_decl::parameter.
* src/abg-comparison.cc: Add doc-string about the internal
representation of the comparison engine and also about the concept
of canonical diff of the comparison engine.
(RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER)
(RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2)
(RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER3): Consider the
canonical diff when trying to know if the current node was
reported earlier.
(diff_context::priv::canonical_diffs): New data member.
(diff_context::{get_canonical_diff_for, set_canonical_diff_for,
set_or_get_canonical_diff_for, initialize_canonical_diff}): Define
new member functions.
(diff_context::{diff_has_been_traversed, mark_diff_as_traversed):
Consider canonical diff for these tests and actions.
(diff::priv::children_): Change the type of this to
vector<diff_sptr>.
(diff::canonical_diff_): New data member.
(diff::diff): Initialize the diff::canonical_diff_ data member.
(diff::begin_traversing): Mark the canonical diff node too.
(diff::is_traversing): Consider the canonical diff node in this
test.
(diff::end_traversing): Make the canonical diff node too. Also
mark the current node as having been traversed.
(diff::children_nodes): Return a vector<diff_sptr> type.
(diff::{get_canonical_diff, set_canonical_diff}): Define new
member functions.
(diff::append_child_node): Take a diff_sptr type parameter.
(diff::{reported_once, currently_reporting}): Flag the canonical
diff node too. And consider the canonical diff node when checking
the flag.
(diff::traverse): No need to mark the node as being traversed
because the diff::end_traversing() function does it now. Adjust
the code because diff::children_nodes() now returns
vector<diff_sptr>.
({distinct_diff, var_diff, pointer_diff, array_diff,
reference_diff, qualified_type_diff, enum_diff, class_diff,
base_diff, scope_diff, function_decl_diff, typedef_diff,
corpus_diff}::chain_into_hierarchy): Adjust to the new type that
diff::append_child_node() takes. Also, take into account that the
diff nodes are now un-shared.
(compute_diff_for_distinct_kinds, compute_diff_for_types)
(compute_diff): Do not share diff nodes anymore. Initialize the
canonical diff node for the new created node.
(represent): Take a var_diff_sptr rather than two var_decl_sptr.
Adjust. Also take in account the fact that diff nodes are not
shared anymore, and that they do have canonical diffs.
(var_diff::type_diff): Make the computation of the type_diff of
the var_diff be lazy. This avoids infinite (recursive) creation
of diff nodes when a class diff node has a sub-type of data member
that is a class diff node too.
(var_diff::report): Detect redundant reporting of this kind of
diff node.
(class_diff::priv::changed_bases_): Change the type of this to
string_base_diff_sptr_map.
(class_diff::priv::subtype_changed_dm_): Change the type of this
to string_var_diff_sptr_map.
(class_diff::priv::changed_dm_): Change the type of this to
unsigned_var_diff_sptr_map.
(class_diff::priv::{count_filtered_subtype_changed_dm,
count_filtered_bases}): Do not take a diff_context_sptr anymore.
(class_diff::ensure_lookup_tables_populated): changed_bases_
subtype_changed_dm_ and changed_dm_ are now *NOT* shared diff
nodes anymore.
(class_diff::priv::base_has_changed): Adjust.
(class_diff::priv::subtype_changed_dm): Adjust.
(class_diff::priv::count_filtered_bases): Adjust as changed_bases_
is now a map of un-shared diff nodes.
(class_diff::priv::count_filtered_subtype_changed_dm): Adjust as
subtype_changed_dm_ is now a map of un-shared diff nodes.
(class_diff::priv::{count_filtered_changed_mem_fns,
count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns,
}): Adjust for change of the default parameter value of
diff_context::maybe_apply_filters().
(class_diff::~class_diff): New destructor.
(class_diff::changed_bases): Return a string_base_diff_sptr_map&
type.
(class_diff::{inserted_data_members, deleted_data_members,
changed_member_fns}): Add doc strings.
(struct changed_data_member_comp): Remove.
(struct var_diff_comp): New comparison functor.
(sort_changed_data_members): Remove.
(sort_var_diffs): Define new sorting function.
(class_diff::report): Adjust.
(fn_parm_diff::*): Define member types and functions of the new
fn_parm_diff type.
(function_decl_diff::priv::{subtype_changed_parms_,
changed_parms_by_id_}): Make these take a map of fn_parm_diff_sptr
nodes.
(function_decl_diff::ensure_lookup_tables_populated): Adjust to
the fact that priv_->subtype_changed_parms_ and
priv_->priv_->changed_parms_by_id_ now are maps of un-shared
fn_parm_diff_sptr nodes.
(function_decl_diff::subtype_changed_parms): Adjust.
(struct changed_parm_comp): Remove.
(struct fn_parm_diff_comp): New comparison functor.
(sort_changed_parm_map): Remove.
(sort_string_fn_parm_diff_sptr_map): New sorting function.
(function_decl_diff::report): Adjust.
(corpus_diff::priv::children_): Change the type of this to
vector<diff_sptr>.
(corpus_diff::priv::changed_fns_): Changed the type of this to
string_function_decl_diff_sptr_map.
(corpus_diff::priv::changed_vars_): Changed the type of this to
string_var_diff_sptr_map.
(corpus_diff::priv::ensure_lookup_tables_populated): Adjust.
(corpus_diff::priv::apply_filters_and_compute_diff_stats}):
Adjust. Do not need to clear redundancy categorization anymore
because the diff nodes are not shared anymore.
(corpus_diff::priv::categorize_redundant_changed_sub_nodes):
Adjust.
(corpus_diff::priv::clear_redundancy_categorization): Adjust.
(corpus_diff::changed_variables): Adjust.
(struct changed_function_ptr_comp): Remove.
(struct function_decl_diff_comp): New comparison functor.
(sort_string_changed_function_ptr_map): Remove.
(sort_string_function_decl_diff_sptr_map): Define new sorting
function.
(struct changed_vars_comp): Remove.
(struct var_diff_sptr_comp): New comparison functor.
(sort_changed_vars): Remove.
(sort_string_var_diff_sptr_map): Define new sorting function.
(corpus_diff::report): Adjust.
(corpus_diff::traverse): Adjust.
({category_propagation_visitor,
suppression_categorization_visitor}::visit_end): Adjust.
(clear_redundancy_categorization): Adjust.
* src/abg-hash.cc (function_decl::parameter::hash::operator):
Adjust.
* src/abg-ir.cc (struct function_decl::parameter::priv): Define
here as part of pimpl-ifying the function_decl::parameter type.
(function_decl::parameter::*): Define here the member functions as
part of pimpl-ifying the function_decl::parameter type.
(equals): Define the overload for function_decl::parameter here
too.
(ir_node_visitor::visit(function_decl::parameter*)): Define this.
* tests/data/test-abicompat/test0-fn-changed-report-0.txt: Adjust.
* tests/data/test-diff-suppr/test5-fn-suppr-report-0.txt: Adjust.
* tests/data/test-diff-dwarf/libtest21-redundant-fn-v0.so: New
test input data.
* tests/data/test-diff-dwarf/libtest21-redundant-fn-v1.so:
Likewise.
* tests/data/test-diff-dwarf/test21-redundant-fn-v0.cc: Source
code for test input binary above.
* tests/data/test-diff-dwarf/test21-redundant-fn-v1.cc: Likewise.
* tests/data/test-diff-dwarf/test21-redundant-fn-report-0.txt: New
test input data.
* tests/data/test-diff-dwarf/libtest22-changed-parm-c-v0.so: New
test input data.
* tests/data/test-diff-dwarf/libtest22-changed-parm-c-v1.so:
Likewise.
* tests/data/test-diff-dwarf/test22-changed-parm-c-v0.c: Source
code for test input binary above.
* tests/data/test-diff-dwarf/test22-changed-parm-c-v1.c: Likewise.
* tests/test-diff-dwarf.cc (in_out_spec): Add the new test input
data to the vector the test inputs to run this harness over.
* tests/data/test-diff-suppr/test8-redundant-fn-report-0.txt: New
test input data.
* tests/data/test-diff-suppr/test8-redundant-fn-report-1.txt:
Likewise.
* tests/data/test-diff-suppr/libtest8-redundant-fn-v0.so: New test
input binary.
* tests/data/test-diff-suppr/libtest8-redundant-fn-v1.so: Likewise.
* tests/data/test-diff-suppr/test8-redundant-fn-v0.cc: Source code
code for binary test input above.
* tests/data/test-diff-suppr/test8-redundant-fn-v1.cc: Likewise.
* tests/data/test-diff-suppr/test9-changed-parm-c-report-0.txt:
New test input data.
* tests/data/test-diff-suppr/test9-changed-parm-c-report-1.txt:
Likewise.
* tests/data/test-diff-suppr/libtest9-changed-parm-c-v0.so: New
test input binary.
* tests/data/test-diff-suppr/libtest9-changed-parm-c-v1.so: New
test input binary.
* tests/data/test-diff-suppr/test9-changed-parm-c-v0.c: Source
code for binary test input above.
* tests/data/test-diff-suppr/test9-changed-parm-c-v1.c: Likewise.
* tests/test-diff-suppr.cc (in_out_specs): Add the new test input
data to the vector the test inputs to run this harness over.
* tests/data/Makefile.am: Add the new files to the source
distribution.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-26 12:22:16 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/libtest21-redundant-fn-v0.so",
|
|
|
|
"data/test-diff-dwarf/libtest21-redundant-fn-v1.so",
|
|
|
|
"data/test-diff-dwarf/test21-redundant-fn-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test21-redundant-fn-report-0.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/libtest22-changed-parm-c-v0.so",
|
|
|
|
"data/test-diff-dwarf/libtest22-changed-parm-c-v1.so",
|
|
|
|
"data/test-diff-dwarf/test22-changed-parm-c-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test22-changed-parm-c-report-0.txt"
|
|
|
|
},
|
2015-01-07 12:45:53 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/libtest-23-diff-arch-v0-32.so",
|
|
|
|
"data/test-diff-dwarf/libtest-23-diff-arch-v0-64.so",
|
|
|
|
"data/test-diff-dwarf/test-23-diff-arch-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test-23-diff-arch-report-0.txt"
|
2015-04-15 13:03:59 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/libtest24-added-fn-parms-v0.so",
|
|
|
|
"data/test-diff-dwarf/libtest24-added-fn-parms-v1.so",
|
|
|
|
"data/test-diff-dwarf/test24-added-fn-parms-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test24-added-fn-parms-report-0.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/libtest25-removed-fn-parms-v0.so",
|
|
|
|
"data/test-diff-dwarf/libtest25-removed-fn-parms-v1.so",
|
|
|
|
"data/test-diff-dwarf/test25-removed-fn-parms-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test25-removed-fn-parms-report-0.txt"
|
2015-01-07 12:45:53 +00:00
|
|
|
},
|
2015-06-04 09:09:23 +00:00
|
|
|
{
|
2015-05-05 08:05:45 +00:00
|
|
|
"data/test-diff-dwarf/libtest26-added-parms-before-variadic-v0.so",
|
|
|
|
"data/test-diff-dwarf/libtest26-added-parms-before-variadic-v1.so",
|
|
|
|
"data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt",
|
|
|
|
"output/test-diff-dwarf/test26-added-parms-before-variadic-report.txt"
|
|
|
|
},
|
2015-06-04 09:09:23 +00:00
|
|
|
{
|
2015-06-02 10:26:11 +00:00
|
|
|
"data/test-diff-dwarf/test27-local-base-diff-v0.o",
|
|
|
|
"data/test-diff-dwarf/test27-local-base-diff-v1.o",
|
|
|
|
"data/test-diff-dwarf/test27-local-base-diff-report.txt",
|
|
|
|
"output/test-diff-dwarf/test27-local-base-diff-report.txt"
|
|
|
|
},
|
2015-06-04 07:22:02 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test28-vtable-changes-v0.o",
|
|
|
|
"data/test-diff-dwarf/test28-vtable-changes-v1.o",
|
|
|
|
"data/test-diff-dwarf/test28-vtable-changes-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test28-vtable-changes-report-0.txt"
|
|
|
|
},
|
Detect vtable changes from member function changes
This patch adds vtable changes detection based on the detection of
virtual member function changes. That is, when a member function
changes, if that member function is virtual, then infer if the change
implies changes to the vtable of the containing class.
Before that patch, we were doing the vtable change detection when we
were comparing two classes; we were then comparing their virtual
member functions. But as for a given class all its virtual member
functions are not necessarily emitted in the DWARF debug info (only
the virtual member functions that are used in a given translation unit
are emitted in that translation unit) it's not reliable to compare
virtual member functions as part of comparing a given class. We thus
decided some patches ago to stop comparing virtual member functions
when we compare two classes.
So with this patch now, we still detect changes to the vtable and emit
an appropriate message to the user.
* include/abg-ir.h (class_decl::{has_virtual_base, has_vtable}):
Declare new member functions.
* src/abg-comp-filter.cc (has_virtual_mem_fn_change): New overload
for function_decl_diff.
(has_virtual_mem_fn_change): In the overload for diff*, support
virtual member function changes detection for function_decl_diff*.
* src/abg-comparison.cc (function_decl_diff::report): Detect and
report changes to a vtable by looking a changes that can happen to
a given member function.
(corpus_diff::report): Detect and report changes to vtables by
looking at changes change to member functions.
* tests/data/test-diff-dwarf/test29-vtable-changes-report-0.txt:
New text input.
* tests/data/test-diff-dwarf/test29-vtable-changes-v{0,1}.cc: Source
code of new test input binaries.
* tests/data/test-diff-dwarf/test29-vtable-changes-v{0,1}.o: New
test input binaries.
* tests/data/test-diff-dwarf/test30-vtable-changes-report-0.txt:
New text input.
* tests/data/test-diff-dwarf/test30-vtable-changes-v{0,1}.cc: New
test input.
* tests/data/test-diff-dwarf/test30-vtable-changes-v{0,1}.o: New
test input binaries.
* tests/data/test-diff-dwarf/test31-vtable-changes-report-0.txt:
New test input.
* tests/data/test-diff-dwarf/test31-vtable-changes-v{0,1}.cc:
Source code of new test input binary.
* tests/data/test-diff-dwarf/test31-vtable-changes-v{0,1}.o: New
test input binary.
* tests/data/Makefile.am: Add the new test input files above to
source distribution.
* tests/test-diff-dwarf.cc (in_out_specs): Consume the new test
inputs above.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-29 13:59:14 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test29-vtable-changes-v0.o",
|
|
|
|
"data/test-diff-dwarf/test29-vtable-changes-v1.o",
|
|
|
|
"data/test-diff-dwarf/test29-vtable-changes-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test29-vtable-changes-report-0.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test30-vtable-changes-v0.o",
|
|
|
|
"data/test-diff-dwarf/test30-vtable-changes-v1.o",
|
|
|
|
"data/test-diff-dwarf/test30-vtable-changes-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test30-vtable-changes-report-0.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test31-vtable-changes-v0.o",
|
|
|
|
"data/test-diff-dwarf/test31-vtable-changes-v1.o",
|
|
|
|
"data/test-diff-dwarf/test31-vtable-changes-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test31-vtable-changes-report-0.txt"
|
|
|
|
},
|
Bug 17340 - Support pointers and references to functions
* include/abg-comparison.h (compute_diff_for_distinct_kinds): Take the
first two arguments of type const type_or_decl_base_sptr instead.
* include/abg-ir.h (translation_unit::get_function_types): Declare new
method.
(function_types): Declare new typedef.
* src/abg-comparison.cc (compute_diff_for_types): Take the first two
arguments of type const type_or_decl_base_sptr instead of a const
decl_base_sptr.
(try_to_diff): Likewise.
(try_to_diff<class_decl>): Likewise.
(try_to_diff_distinct_kinds): Likewise.
(compute_diff_for_distinct_kinds): Likewise. Also remove a variant
accepting arguments of type const type_base_sptr.
* src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Skip
building a pointer if it points to the beginning of a vptr.
(build_pointer_type_def): Declare utype_decl of type
type_or_decl_base_sptr and adjust assignments to it accordingly.
(build_function_type): New function definition.
(build_function_decl): Call build_function_type instead of building
an ftype manually.
(build_ir_node_from_die): Amend case DW_TAG_subroutine_type with
appropriate calls to build a function type.
* src/abg-ir.cc (translation_unit::get_function_types): New method
definition.
({pointer,reference}_type_def::pointer_type_def): Expect that
pointed_to might not have an accompanying declaration and set a type's
name in this case as well.
({pointer,reference}_type_def::get_qualified_name): Generate a
qualified name even if the pointed-to type has no declaration.
* src/abg-reader.cc (build_function_type): New function definition.
(handle_element_node): Return a type_or_decl_base_sptr instead and
try calling handle_function_type in addition to others.
(handle_function_type): New function definition that calls
build_function_type.
(build_type): Try calling build_function_type as well.
* src/abg-writer.cc (fn_shared_ptr_map): Declare new typedef.
(write_context::{clear_referenced_fntypes_map,fntype_is_referenced,
record_fntype_as_referenced}): New member functions.
(write_translation_unit): Call the new clear_referenced_fntypes_map.
* tests/data/Makefile.am: Add the new test material to the build
system.
(write_translation_unit): Separately write function types that have
been recorded to emit by write_{pointer,reference}_type_def.
(write_{pointer,reference}_type_def): Record the type pointed to as
a type to be emitted if type == function type.
(write_function_type): Write the details of a function type in the
abixml format and unmark the type.
* tests/data/test-diff-dwarf/test32-fnptr-changes-report-0.txt: New
test reference report.
* tests/data/test-diff-dwarf/test32-fnptr-changes-v{0,1}.cc: New test
source files.
* tests/data/test-diff-dwarf/test32-fnptr-changes-v{0,1}.o: New binary
test inputs.
* tests/data/test-diff-dwarf/test33-fnref-changes-report-0.txt: New
test reference report.
* tests/data/test-diff-dwarf/test33-fnref-changes-v{0,1}.cc: New test
source files.
* tests/data/test-diff-dwarf/test33-fnref-changes-v{0,1}.o: New binary
test inputs.
* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
Adjust.
* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
Likewise.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
* 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/test9-pr18818-clang.so.abi: Likewise.
* tests/data/test-read-write/test27.xml: New test source file.
* tests/test-diff-dwarf.cc: Adjust to launch the new tests.
* tests/test-read-write.cc: Likewise.
Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-09-23 06:44:00 +00:00
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test32-fnptr-changes-v0.o",
|
|
|
|
"data/test-diff-dwarf/test32-fnptr-changes-v1.o",
|
|
|
|
"data/test-diff-dwarf/test32-fnptr-changes-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test32-fnptr-changes-report-0.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-diff-dwarf/test33-fnref-changes-v0.o",
|
|
|
|
"data/test-diff-dwarf/test33-fnref-changes-v1.o",
|
|
|
|
"data/test-diff-dwarf/test33-fnref-changes-report-0.txt",
|
|
|
|
"output/test-diff-dwarf/test33-fnref-changes-report-0.txt"
|
|
|
|
},
|
2014-03-21 14:15:02 +00:00
|
|
|
// This should be the last entry
|
|
|
|
{NULL, NULL, NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
int
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
using abigail::tests::get_src_dir;
|
|
|
|
using abigail::tests::get_build_dir;
|
2015-01-08 10:34:03 +00:00
|
|
|
using abigail::tools_utils::ensure_parent_dir_created;
|
2014-03-21 14:15:02 +00:00
|
|
|
using abigail::dwarf_reader::read_corpus_from_elf;
|
|
|
|
using abigail::comparison::compute_diff;
|
|
|
|
using abigail::comparison::corpus_diff_sptr;
|
Introduce the concept of environment
There are resources needed by the type system and other artifacts of
libabigail. Today, when the life time of those resources need to be
greater than all of artifacts of Abigail, then said resources are made
global.
But then global resources are not great, if anything because they
complicate the future use of the library in concurrent computing
setups.
As I was in the need to add one resource to be used by the type
system, I decided to sit down and first overhaul how these long lived
resources needed to be handled.
And here comes the concept of "environment". An environment is a
place where one can put resources that need to live longer than all
the other artifacts of the Abigail system. And so, the code that
creates Abigail artifacts needs and environment of for said artifacts
to use. In other words, artifacts now use an environment.
This has interesting and strong implications. We can only compare two
artifacts if they use the same environment. This is quite a strong
requirement.
But then when this requirement is fulfilled, comparing two types
amounts to just comparing two pointer values; hash values for types
can also be cached. Now *that* is great for speed of comparison, is
it not?
This patch introduce the concept environment (which is basically a new
abigail::ir::environment type), removes the global variables and uses
the environment instead. Each ABI artifact (either type or decl) now
has a ::get_environment() member function to get its environment.
This patch also disables the caching of hash values because the
caching must happen only *after* all types have been canonicalized.
We were not respecting that requirement until now, and that introduces
wrong hash values. A subsequent patch is going to re-introduce hash
value caching again, once the infrastructure is in place to set a flag
in the environment (hah!) once type canonicalization is done, and then
later read that flag when some client code requests a hash value, to
know if we should look in the hash value cache or not.
The patch obviously changes the output of numerous regression tests
(if anything b/c it disables hash value caching) so 'make check'
yields regressions. But then, it's only the subsequent patch that
updates the tests.
* include/abg-ir.h: Adjust note about memory management.
(class environment): Declare new class.
(translation_unit::translation_unit): Take an environment in
parameter.
(translation_unit::{g,s}et_environment): Declare new member
functions.
(type_or_decl_base::{g,s}et_environment): Likewise.
(type_or_decl_base::{get_cached_hash_value,
set_cached_hash_value}): Change the name of
decl_base::peek_hash_value() and decl_base::set_hash() here into
these and move them here.
(type_or_decl_base::hashing_started): Move
decl_base::hashing_started() here.
({g,s}et_environment_for_artifact): Declare new functions.
(class decl_base): Move member functions hashing_started(),
peek_hash_value() and set_hash() on to the type_or_decl_base base
class.
(scope_decl::scope_decl): Initialize the virtual member
type_or_decl_base().
(type_decl::{get_void_type_decl,
get_variadic_parameter_type_decl}): Remove these static member
functions. They are now non-static member functions of the new
environment type.
* src/abg-ir.cc (class environment_setter): New internal class.
(get_canonical_types_map): Remove. This now becomes a member
function of the environment type.
(class usage_watchdog): Remove.
(usage_watchdog_{s,w}ptr): Remove these typedefs.
(get_usage_watchdog_wptr, ref_usage_watchdog)
(maybe_cleanup_type_system_data): Remove these functions.
(translation_unit::priv::usage_watchdog_): Remove data member.
(translation_unit::priv::env_): New data member.
(translation_unit::priv::priv): Take an environment and initialize
the new env_ data member. Do not initialize the removed
usage_watchdog_.
(translation_unit::translation_unit): Take an environment
parameter.
(translation_unit::get_global_scope): Set the environment of a new
global scope.
(translation_unit::{g,s}et_environment): New accessors.
(translation_unit::bind_function_type_life_time): Set the
environment of the function type.
(struct environment::priv): New class.
(environment::{environment, ~environment, get_canonical_types_map,
get_variadic_parameter_type_decl, canonicalization_is_done}): New
member functions.
(struct type_or_decl_base::priv): New class.
(type_or_decl_base::{type_or_decl_base, hashing_started,
get_cached_hash_value, set_cached_hash_value, set_environment,
get_environment, traverse}): New member functions.
({s,g}get_environment_for_artifact): New functions.
(decl_base::priv::{hash_, hashing_started}): Remove.
(decl_base::priv::priv): Adjust.
(decl_base::decl_base): In the copy constructor, initialize the
virtual base type_or_decl_base. Do not initialize hash_ and
hashing_started data member that got removed.
(decl_base::{hashing_started, peek_hash_value, set_hash}): Remove
member functions.
(strip_typedef): Set the environment of the new type which has its
typedefs stripped off. Adjust the call to type_or_void().
(scope_decl::{add, insert}_member_decl): Set the environment of
the new member decl to the environment of its scope.
(synthesize_type_from_translation_unit)
(synthesize_function_type_from_translation_unit): Set the
environment for the newly synthesized type. Adjust calls to
type_or_void().
(type_or_void): Take an environment in parameter. Get the void
type from the environment.
(get_canonical_types_map): Remove.
(type_base::get_canonical_type_for): Get the canonical types map
from the environment, not from a global variable.
(type_decl::{get_void_type_decl,
get_variadic_parameter_type_decl}): Remove.
(pointer_type_def::pointer_type_def): Adjust call to type_or_void.
(reference_type_def::reference_type_def): Likewise.
(function_decl::parameter::get_pretty_representation): Get the
variadic parameter type decl from the environment.
(class_decl::priv::classes_being_compared_): Remove static data
member.
(class_decl::priv::{mark_as_being_compared,
unmark_as_being_compared, comparison_started): Use the "classes
being compared" map from the environment.
(class_decl::base_spec::get_hash): Adjust.
(keep_type_alive): Get the alive types array from the environment)
not from a global variable anymore.
(get_next_string): Put the counter in thread-local storage.
* src/abg-hash.cc (scope_decl::hash::operator())
(function_decl::hash::operator()): Do not handle caching (here).
* include/abg-corpus.h (corpus::{g,s}et_environment): Declare new
accessors.
* src/abg-corpus.cc (corpus::priv::env): New data member.
(corpus::priv::priv): Initialize it.
(corpus::corpus): Take an environment in parameter.
(corpus::{g,s}et_environment): Define new member functions
(corpus::add): Set the environment of the newly added translation
unit, if it's not set already set. In any case, assert that the
translation unit must use the same environment as the corpus.
* include/abg-dwarf-reader.h (create_read_context)
(read_corpus_from_elf): Take an environment parameter.
({s,g}et_debug_info_root_path, {s,g}et_environment): Declare new
functions.
* src/abg-dwarf-reader.cc (read_context::{env_,
offline_callbacks_}): New data members.
(read_context::read_context): Initialize them.
(read_context::clear_per_translation_unit_data): Do not touch the
void type declaration, it doesn't belong to the translation unit.
(read_context::{env, offline_callbacks}): New accessors.
(read_context::{create_default_dwfl}): New member function.
(read_context::dwfl_handle): Add a setter overload.
({s,g}et_debug_info_root_path): Define new accessors.
(create_default_dwfl, create_dwfl_sptr, create_default_dwfl_sptr):
Remove these.
(build_translation_unit_and_add_to_ir): Adjust to pass the
environment to the newly created translation unit.
(build_function_decl): Adjust to pass the environment to the
created function and parameter types. Get variadic parameter type
node from the current environment, not from a global variable.
And do not try to canonicalize function types here.
(read_debug_info_into_corpus): Set the environment of the newly
created corpus.
(build_ir_node_for_void_type): Get the void type node from the
current environment, rather than from a global variable.
(create_read_context): Take the environment in parameter.
Create the default dwarf front end library handle using the new
member function of the read context. Set the current environment
used by the reader.
(read_corpus_from_elf): Take an environment in
parameter. Overhaul. This is now simpler.
(has_alt_debug_info): Adjust the call to create_read_context() to
make it pass an empty environment.
* include/abg-fwd.h (class environment): Forward declare.
* include/abg-reader.h (read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream)
(read_corpus_from_native_xml): Take an environment in parameter.
* src/abg-reader.cc (read_context::m_env): New data member.
(read_context::read_context): Initialize it.
(read_context::{get_environment, set_environment}): New data
member.
(read_translation_unit): Set environment of the new translation
unit.
(read_corpus_from_input): Set the environment of the new corpus.
(read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream, read_corpus_from_native_xml):
Take an environment in parameter.
(build_function_parameter): Get variadic parameter type from the environment.
* src/abg-comparison.cc (compute_diff): Add asserts in all the
overloads to ensure that the artifact being compared come from the
same environment.
* tests/print-diff-tree.cc (main): Create an env for the ABI
artifacts to use.
* tests/test-abidiff.cc (main): Likewise.
* tests/test-diff-dwarf.cc (main): Likewise.
* tests/test-ir-walker.cc (main): Likewise.
* tests/test-read-dwarf.cc (main): Likewise.
* tests/test-read-write.cc (main): Likewise.
* tools/abicompat.cc (main): Likewise.
* tools/abidiff.cc (main): Likewise.
* tools/abidw.cc (main): Likewise.
* tools/abilint.cc (main): Likewise.
* tools/abipkgdiff.cc (main): Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-07 20:27:50 +00:00
|
|
|
using abigail::ir::environment;
|
|
|
|
using abigail::ir::environment_sptr;
|
2014-03-21 14:15:02 +00:00
|
|
|
|
|
|
|
bool is_ok = true;
|
|
|
|
string in_elfv0_path, in_elfv1_path,
|
|
|
|
ref_diff_report_path, out_diff_report_path;
|
|
|
|
|
|
|
|
for (InOutSpec* s = in_out_specs; s->in_elfv0_path; ++s)
|
|
|
|
{
|
|
|
|
in_elfv0_path = get_src_dir() + "/tests/" + s->in_elfv0_path;
|
|
|
|
in_elfv1_path = get_src_dir() + "/tests/" + s->in_elfv1_path;
|
|
|
|
out_diff_report_path = get_build_dir() + "/tests/" + s->out_report_path;
|
|
|
|
|
|
|
|
if (!ensure_parent_dir_created(out_diff_report_path))
|
|
|
|
{
|
2014-03-29 08:05:21 +00:00
|
|
|
cerr << "could not create parent directory for "
|
2014-03-21 14:15:02 +00:00
|
|
|
<< out_diff_report_path;
|
|
|
|
is_ok = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-07-08 12:40:51 +00:00
|
|
|
abigail::dwarf_reader::status status =
|
|
|
|
abigail::dwarf_reader::STATUS_UNKNOWN;
|
|
|
|
|
Introduce the concept of environment
There are resources needed by the type system and other artifacts of
libabigail. Today, when the life time of those resources need to be
greater than all of artifacts of Abigail, then said resources are made
global.
But then global resources are not great, if anything because they
complicate the future use of the library in concurrent computing
setups.
As I was in the need to add one resource to be used by the type
system, I decided to sit down and first overhaul how these long lived
resources needed to be handled.
And here comes the concept of "environment". An environment is a
place where one can put resources that need to live longer than all
the other artifacts of the Abigail system. And so, the code that
creates Abigail artifacts needs and environment of for said artifacts
to use. In other words, artifacts now use an environment.
This has interesting and strong implications. We can only compare two
artifacts if they use the same environment. This is quite a strong
requirement.
But then when this requirement is fulfilled, comparing two types
amounts to just comparing two pointer values; hash values for types
can also be cached. Now *that* is great for speed of comparison, is
it not?
This patch introduce the concept environment (which is basically a new
abigail::ir::environment type), removes the global variables and uses
the environment instead. Each ABI artifact (either type or decl) now
has a ::get_environment() member function to get its environment.
This patch also disables the caching of hash values because the
caching must happen only *after* all types have been canonicalized.
We were not respecting that requirement until now, and that introduces
wrong hash values. A subsequent patch is going to re-introduce hash
value caching again, once the infrastructure is in place to set a flag
in the environment (hah!) once type canonicalization is done, and then
later read that flag when some client code requests a hash value, to
know if we should look in the hash value cache or not.
The patch obviously changes the output of numerous regression tests
(if anything b/c it disables hash value caching) so 'make check'
yields regressions. But then, it's only the subsequent patch that
updates the tests.
* include/abg-ir.h: Adjust note about memory management.
(class environment): Declare new class.
(translation_unit::translation_unit): Take an environment in
parameter.
(translation_unit::{g,s}et_environment): Declare new member
functions.
(type_or_decl_base::{g,s}et_environment): Likewise.
(type_or_decl_base::{get_cached_hash_value,
set_cached_hash_value}): Change the name of
decl_base::peek_hash_value() and decl_base::set_hash() here into
these and move them here.
(type_or_decl_base::hashing_started): Move
decl_base::hashing_started() here.
({g,s}et_environment_for_artifact): Declare new functions.
(class decl_base): Move member functions hashing_started(),
peek_hash_value() and set_hash() on to the type_or_decl_base base
class.
(scope_decl::scope_decl): Initialize the virtual member
type_or_decl_base().
(type_decl::{get_void_type_decl,
get_variadic_parameter_type_decl}): Remove these static member
functions. They are now non-static member functions of the new
environment type.
* src/abg-ir.cc (class environment_setter): New internal class.
(get_canonical_types_map): Remove. This now becomes a member
function of the environment type.
(class usage_watchdog): Remove.
(usage_watchdog_{s,w}ptr): Remove these typedefs.
(get_usage_watchdog_wptr, ref_usage_watchdog)
(maybe_cleanup_type_system_data): Remove these functions.
(translation_unit::priv::usage_watchdog_): Remove data member.
(translation_unit::priv::env_): New data member.
(translation_unit::priv::priv): Take an environment and initialize
the new env_ data member. Do not initialize the removed
usage_watchdog_.
(translation_unit::translation_unit): Take an environment
parameter.
(translation_unit::get_global_scope): Set the environment of a new
global scope.
(translation_unit::{g,s}et_environment): New accessors.
(translation_unit::bind_function_type_life_time): Set the
environment of the function type.
(struct environment::priv): New class.
(environment::{environment, ~environment, get_canonical_types_map,
get_variadic_parameter_type_decl, canonicalization_is_done}): New
member functions.
(struct type_or_decl_base::priv): New class.
(type_or_decl_base::{type_or_decl_base, hashing_started,
get_cached_hash_value, set_cached_hash_value, set_environment,
get_environment, traverse}): New member functions.
({s,g}get_environment_for_artifact): New functions.
(decl_base::priv::{hash_, hashing_started}): Remove.
(decl_base::priv::priv): Adjust.
(decl_base::decl_base): In the copy constructor, initialize the
virtual base type_or_decl_base. Do not initialize hash_ and
hashing_started data member that got removed.
(decl_base::{hashing_started, peek_hash_value, set_hash}): Remove
member functions.
(strip_typedef): Set the environment of the new type which has its
typedefs stripped off. Adjust the call to type_or_void().
(scope_decl::{add, insert}_member_decl): Set the environment of
the new member decl to the environment of its scope.
(synthesize_type_from_translation_unit)
(synthesize_function_type_from_translation_unit): Set the
environment for the newly synthesized type. Adjust calls to
type_or_void().
(type_or_void): Take an environment in parameter. Get the void
type from the environment.
(get_canonical_types_map): Remove.
(type_base::get_canonical_type_for): Get the canonical types map
from the environment, not from a global variable.
(type_decl::{get_void_type_decl,
get_variadic_parameter_type_decl}): Remove.
(pointer_type_def::pointer_type_def): Adjust call to type_or_void.
(reference_type_def::reference_type_def): Likewise.
(function_decl::parameter::get_pretty_representation): Get the
variadic parameter type decl from the environment.
(class_decl::priv::classes_being_compared_): Remove static data
member.
(class_decl::priv::{mark_as_being_compared,
unmark_as_being_compared, comparison_started): Use the "classes
being compared" map from the environment.
(class_decl::base_spec::get_hash): Adjust.
(keep_type_alive): Get the alive types array from the environment)
not from a global variable anymore.
(get_next_string): Put the counter in thread-local storage.
* src/abg-hash.cc (scope_decl::hash::operator())
(function_decl::hash::operator()): Do not handle caching (here).
* include/abg-corpus.h (corpus::{g,s}et_environment): Declare new
accessors.
* src/abg-corpus.cc (corpus::priv::env): New data member.
(corpus::priv::priv): Initialize it.
(corpus::corpus): Take an environment in parameter.
(corpus::{g,s}et_environment): Define new member functions
(corpus::add): Set the environment of the newly added translation
unit, if it's not set already set. In any case, assert that the
translation unit must use the same environment as the corpus.
* include/abg-dwarf-reader.h (create_read_context)
(read_corpus_from_elf): Take an environment parameter.
({s,g}et_debug_info_root_path, {s,g}et_environment): Declare new
functions.
* src/abg-dwarf-reader.cc (read_context::{env_,
offline_callbacks_}): New data members.
(read_context::read_context): Initialize them.
(read_context::clear_per_translation_unit_data): Do not touch the
void type declaration, it doesn't belong to the translation unit.
(read_context::{env, offline_callbacks}): New accessors.
(read_context::{create_default_dwfl}): New member function.
(read_context::dwfl_handle): Add a setter overload.
({s,g}et_debug_info_root_path): Define new accessors.
(create_default_dwfl, create_dwfl_sptr, create_default_dwfl_sptr):
Remove these.
(build_translation_unit_and_add_to_ir): Adjust to pass the
environment to the newly created translation unit.
(build_function_decl): Adjust to pass the environment to the
created function and parameter types. Get variadic parameter type
node from the current environment, not from a global variable.
And do not try to canonicalize function types here.
(read_debug_info_into_corpus): Set the environment of the newly
created corpus.
(build_ir_node_for_void_type): Get the void type node from the
current environment, rather than from a global variable.
(create_read_context): Take the environment in parameter.
Create the default dwarf front end library handle using the new
member function of the read context. Set the current environment
used by the reader.
(read_corpus_from_elf): Take an environment in
parameter. Overhaul. This is now simpler.
(has_alt_debug_info): Adjust the call to create_read_context() to
make it pass an empty environment.
* include/abg-fwd.h (class environment): Forward declare.
* include/abg-reader.h (read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream)
(read_corpus_from_native_xml): Take an environment in parameter.
* src/abg-reader.cc (read_context::m_env): New data member.
(read_context::read_context): Initialize it.
(read_context::{get_environment, set_environment}): New data
member.
(read_translation_unit): Set environment of the new translation
unit.
(read_corpus_from_input): Set the environment of the new corpus.
(read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream, read_corpus_from_native_xml):
Take an environment in parameter.
(build_function_parameter): Get variadic parameter type from the environment.
* src/abg-comparison.cc (compute_diff): Add asserts in all the
overloads to ensure that the artifact being compared come from the
same environment.
* tests/print-diff-tree.cc (main): Create an env for the ABI
artifacts to use.
* tests/test-abidiff.cc (main): Likewise.
* tests/test-diff-dwarf.cc (main): Likewise.
* tests/test-ir-walker.cc (main): Likewise.
* tests/test-read-dwarf.cc (main): Likewise.
* tests/test-read-write.cc (main): Likewise.
* tools/abicompat.cc (main): Likewise.
* tools/abidiff.cc (main): Likewise.
* tools/abidw.cc (main): Likewise.
* tools/abilint.cc (main): Likewise.
* tools/abipkgdiff.cc (main): Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-07 20:27:50 +00:00
|
|
|
environment_sptr env(new environment);
|
2015-07-08 12:40:51 +00:00
|
|
|
abigail::corpus_sptr corp0 =
|
|
|
|
read_corpus_from_elf(in_elfv0_path,
|
|
|
|
/*debug_info_root_path=*/0,
|
Introduce the concept of environment
There are resources needed by the type system and other artifacts of
libabigail. Today, when the life time of those resources need to be
greater than all of artifacts of Abigail, then said resources are made
global.
But then global resources are not great, if anything because they
complicate the future use of the library in concurrent computing
setups.
As I was in the need to add one resource to be used by the type
system, I decided to sit down and first overhaul how these long lived
resources needed to be handled.
And here comes the concept of "environment". An environment is a
place where one can put resources that need to live longer than all
the other artifacts of the Abigail system. And so, the code that
creates Abigail artifacts needs and environment of for said artifacts
to use. In other words, artifacts now use an environment.
This has interesting and strong implications. We can only compare two
artifacts if they use the same environment. This is quite a strong
requirement.
But then when this requirement is fulfilled, comparing two types
amounts to just comparing two pointer values; hash values for types
can also be cached. Now *that* is great for speed of comparison, is
it not?
This patch introduce the concept environment (which is basically a new
abigail::ir::environment type), removes the global variables and uses
the environment instead. Each ABI artifact (either type or decl) now
has a ::get_environment() member function to get its environment.
This patch also disables the caching of hash values because the
caching must happen only *after* all types have been canonicalized.
We were not respecting that requirement until now, and that introduces
wrong hash values. A subsequent patch is going to re-introduce hash
value caching again, once the infrastructure is in place to set a flag
in the environment (hah!) once type canonicalization is done, and then
later read that flag when some client code requests a hash value, to
know if we should look in the hash value cache or not.
The patch obviously changes the output of numerous regression tests
(if anything b/c it disables hash value caching) so 'make check'
yields regressions. But then, it's only the subsequent patch that
updates the tests.
* include/abg-ir.h: Adjust note about memory management.
(class environment): Declare new class.
(translation_unit::translation_unit): Take an environment in
parameter.
(translation_unit::{g,s}et_environment): Declare new member
functions.
(type_or_decl_base::{g,s}et_environment): Likewise.
(type_or_decl_base::{get_cached_hash_value,
set_cached_hash_value}): Change the name of
decl_base::peek_hash_value() and decl_base::set_hash() here into
these and move them here.
(type_or_decl_base::hashing_started): Move
decl_base::hashing_started() here.
({g,s}et_environment_for_artifact): Declare new functions.
(class decl_base): Move member functions hashing_started(),
peek_hash_value() and set_hash() on to the type_or_decl_base base
class.
(scope_decl::scope_decl): Initialize the virtual member
type_or_decl_base().
(type_decl::{get_void_type_decl,
get_variadic_parameter_type_decl}): Remove these static member
functions. They are now non-static member functions of the new
environment type.
* src/abg-ir.cc (class environment_setter): New internal class.
(get_canonical_types_map): Remove. This now becomes a member
function of the environment type.
(class usage_watchdog): Remove.
(usage_watchdog_{s,w}ptr): Remove these typedefs.
(get_usage_watchdog_wptr, ref_usage_watchdog)
(maybe_cleanup_type_system_data): Remove these functions.
(translation_unit::priv::usage_watchdog_): Remove data member.
(translation_unit::priv::env_): New data member.
(translation_unit::priv::priv): Take an environment and initialize
the new env_ data member. Do not initialize the removed
usage_watchdog_.
(translation_unit::translation_unit): Take an environment
parameter.
(translation_unit::get_global_scope): Set the environment of a new
global scope.
(translation_unit::{g,s}et_environment): New accessors.
(translation_unit::bind_function_type_life_time): Set the
environment of the function type.
(struct environment::priv): New class.
(environment::{environment, ~environment, get_canonical_types_map,
get_variadic_parameter_type_decl, canonicalization_is_done}): New
member functions.
(struct type_or_decl_base::priv): New class.
(type_or_decl_base::{type_or_decl_base, hashing_started,
get_cached_hash_value, set_cached_hash_value, set_environment,
get_environment, traverse}): New member functions.
({s,g}get_environment_for_artifact): New functions.
(decl_base::priv::{hash_, hashing_started}): Remove.
(decl_base::priv::priv): Adjust.
(decl_base::decl_base): In the copy constructor, initialize the
virtual base type_or_decl_base. Do not initialize hash_ and
hashing_started data member that got removed.
(decl_base::{hashing_started, peek_hash_value, set_hash}): Remove
member functions.
(strip_typedef): Set the environment of the new type which has its
typedefs stripped off. Adjust the call to type_or_void().
(scope_decl::{add, insert}_member_decl): Set the environment of
the new member decl to the environment of its scope.
(synthesize_type_from_translation_unit)
(synthesize_function_type_from_translation_unit): Set the
environment for the newly synthesized type. Adjust calls to
type_or_void().
(type_or_void): Take an environment in parameter. Get the void
type from the environment.
(get_canonical_types_map): Remove.
(type_base::get_canonical_type_for): Get the canonical types map
from the environment, not from a global variable.
(type_decl::{get_void_type_decl,
get_variadic_parameter_type_decl}): Remove.
(pointer_type_def::pointer_type_def): Adjust call to type_or_void.
(reference_type_def::reference_type_def): Likewise.
(function_decl::parameter::get_pretty_representation): Get the
variadic parameter type decl from the environment.
(class_decl::priv::classes_being_compared_): Remove static data
member.
(class_decl::priv::{mark_as_being_compared,
unmark_as_being_compared, comparison_started): Use the "classes
being compared" map from the environment.
(class_decl::base_spec::get_hash): Adjust.
(keep_type_alive): Get the alive types array from the environment)
not from a global variable anymore.
(get_next_string): Put the counter in thread-local storage.
* src/abg-hash.cc (scope_decl::hash::operator())
(function_decl::hash::operator()): Do not handle caching (here).
* include/abg-corpus.h (corpus::{g,s}et_environment): Declare new
accessors.
* src/abg-corpus.cc (corpus::priv::env): New data member.
(corpus::priv::priv): Initialize it.
(corpus::corpus): Take an environment in parameter.
(corpus::{g,s}et_environment): Define new member functions
(corpus::add): Set the environment of the newly added translation
unit, if it's not set already set. In any case, assert that the
translation unit must use the same environment as the corpus.
* include/abg-dwarf-reader.h (create_read_context)
(read_corpus_from_elf): Take an environment parameter.
({s,g}et_debug_info_root_path, {s,g}et_environment): Declare new
functions.
* src/abg-dwarf-reader.cc (read_context::{env_,
offline_callbacks_}): New data members.
(read_context::read_context): Initialize them.
(read_context::clear_per_translation_unit_data): Do not touch the
void type declaration, it doesn't belong to the translation unit.
(read_context::{env, offline_callbacks}): New accessors.
(read_context::{create_default_dwfl}): New member function.
(read_context::dwfl_handle): Add a setter overload.
({s,g}et_debug_info_root_path): Define new accessors.
(create_default_dwfl, create_dwfl_sptr, create_default_dwfl_sptr):
Remove these.
(build_translation_unit_and_add_to_ir): Adjust to pass the
environment to the newly created translation unit.
(build_function_decl): Adjust to pass the environment to the
created function and parameter types. Get variadic parameter type
node from the current environment, not from a global variable.
And do not try to canonicalize function types here.
(read_debug_info_into_corpus): Set the environment of the newly
created corpus.
(build_ir_node_for_void_type): Get the void type node from the
current environment, rather than from a global variable.
(create_read_context): Take the environment in parameter.
Create the default dwarf front end library handle using the new
member function of the read context. Set the current environment
used by the reader.
(read_corpus_from_elf): Take an environment in
parameter. Overhaul. This is now simpler.
(has_alt_debug_info): Adjust the call to create_read_context() to
make it pass an empty environment.
* include/abg-fwd.h (class environment): Forward declare.
* include/abg-reader.h (read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream)
(read_corpus_from_native_xml): Take an environment in parameter.
* src/abg-reader.cc (read_context::m_env): New data member.
(read_context::read_context): Initialize it.
(read_context::{get_environment, set_environment}): New data
member.
(read_translation_unit): Set environment of the new translation
unit.
(read_corpus_from_input): Set the environment of the new corpus.
(read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream, read_corpus_from_native_xml):
Take an environment in parameter.
(build_function_parameter): Get variadic parameter type from the environment.
* src/abg-comparison.cc (compute_diff): Add asserts in all the
overloads to ensure that the artifact being compared come from the
same environment.
* tests/print-diff-tree.cc (main): Create an env for the ABI
artifacts to use.
* tests/test-abidiff.cc (main): Likewise.
* tests/test-diff-dwarf.cc (main): Likewise.
* tests/test-ir-walker.cc (main): Likewise.
* tests/test-read-dwarf.cc (main): Likewise.
* tests/test-read-write.cc (main): Likewise.
* tools/abicompat.cc (main): Likewise.
* tools/abidiff.cc (main): Likewise.
* tools/abidw.cc (main): Likewise.
* tools/abilint.cc (main): Likewise.
* tools/abipkgdiff.cc (main): Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-07 20:27:50 +00:00
|
|
|
env.get(),
|
2015-07-08 12:40:51 +00:00
|
|
|
/*load_all_types=*/false,
|
|
|
|
status);
|
|
|
|
|
|
|
|
abigail::corpus_sptr corp1 =
|
|
|
|
read_corpus_from_elf(in_elfv1_path,
|
|
|
|
/*debug_info_root_path=*/0,
|
Introduce the concept of environment
There are resources needed by the type system and other artifacts of
libabigail. Today, when the life time of those resources need to be
greater than all of artifacts of Abigail, then said resources are made
global.
But then global resources are not great, if anything because they
complicate the future use of the library in concurrent computing
setups.
As I was in the need to add one resource to be used by the type
system, I decided to sit down and first overhaul how these long lived
resources needed to be handled.
And here comes the concept of "environment". An environment is a
place where one can put resources that need to live longer than all
the other artifacts of the Abigail system. And so, the code that
creates Abigail artifacts needs and environment of for said artifacts
to use. In other words, artifacts now use an environment.
This has interesting and strong implications. We can only compare two
artifacts if they use the same environment. This is quite a strong
requirement.
But then when this requirement is fulfilled, comparing two types
amounts to just comparing two pointer values; hash values for types
can also be cached. Now *that* is great for speed of comparison, is
it not?
This patch introduce the concept environment (which is basically a new
abigail::ir::environment type), removes the global variables and uses
the environment instead. Each ABI artifact (either type or decl) now
has a ::get_environment() member function to get its environment.
This patch also disables the caching of hash values because the
caching must happen only *after* all types have been canonicalized.
We were not respecting that requirement until now, and that introduces
wrong hash values. A subsequent patch is going to re-introduce hash
value caching again, once the infrastructure is in place to set a flag
in the environment (hah!) once type canonicalization is done, and then
later read that flag when some client code requests a hash value, to
know if we should look in the hash value cache or not.
The patch obviously changes the output of numerous regression tests
(if anything b/c it disables hash value caching) so 'make check'
yields regressions. But then, it's only the subsequent patch that
updates the tests.
* include/abg-ir.h: Adjust note about memory management.
(class environment): Declare new class.
(translation_unit::translation_unit): Take an environment in
parameter.
(translation_unit::{g,s}et_environment): Declare new member
functions.
(type_or_decl_base::{g,s}et_environment): Likewise.
(type_or_decl_base::{get_cached_hash_value,
set_cached_hash_value}): Change the name of
decl_base::peek_hash_value() and decl_base::set_hash() here into
these and move them here.
(type_or_decl_base::hashing_started): Move
decl_base::hashing_started() here.
({g,s}et_environment_for_artifact): Declare new functions.
(class decl_base): Move member functions hashing_started(),
peek_hash_value() and set_hash() on to the type_or_decl_base base
class.
(scope_decl::scope_decl): Initialize the virtual member
type_or_decl_base().
(type_decl::{get_void_type_decl,
get_variadic_parameter_type_decl}): Remove these static member
functions. They are now non-static member functions of the new
environment type.
* src/abg-ir.cc (class environment_setter): New internal class.
(get_canonical_types_map): Remove. This now becomes a member
function of the environment type.
(class usage_watchdog): Remove.
(usage_watchdog_{s,w}ptr): Remove these typedefs.
(get_usage_watchdog_wptr, ref_usage_watchdog)
(maybe_cleanup_type_system_data): Remove these functions.
(translation_unit::priv::usage_watchdog_): Remove data member.
(translation_unit::priv::env_): New data member.
(translation_unit::priv::priv): Take an environment and initialize
the new env_ data member. Do not initialize the removed
usage_watchdog_.
(translation_unit::translation_unit): Take an environment
parameter.
(translation_unit::get_global_scope): Set the environment of a new
global scope.
(translation_unit::{g,s}et_environment): New accessors.
(translation_unit::bind_function_type_life_time): Set the
environment of the function type.
(struct environment::priv): New class.
(environment::{environment, ~environment, get_canonical_types_map,
get_variadic_parameter_type_decl, canonicalization_is_done}): New
member functions.
(struct type_or_decl_base::priv): New class.
(type_or_decl_base::{type_or_decl_base, hashing_started,
get_cached_hash_value, set_cached_hash_value, set_environment,
get_environment, traverse}): New member functions.
({s,g}get_environment_for_artifact): New functions.
(decl_base::priv::{hash_, hashing_started}): Remove.
(decl_base::priv::priv): Adjust.
(decl_base::decl_base): In the copy constructor, initialize the
virtual base type_or_decl_base. Do not initialize hash_ and
hashing_started data member that got removed.
(decl_base::{hashing_started, peek_hash_value, set_hash}): Remove
member functions.
(strip_typedef): Set the environment of the new type which has its
typedefs stripped off. Adjust the call to type_or_void().
(scope_decl::{add, insert}_member_decl): Set the environment of
the new member decl to the environment of its scope.
(synthesize_type_from_translation_unit)
(synthesize_function_type_from_translation_unit): Set the
environment for the newly synthesized type. Adjust calls to
type_or_void().
(type_or_void): Take an environment in parameter. Get the void
type from the environment.
(get_canonical_types_map): Remove.
(type_base::get_canonical_type_for): Get the canonical types map
from the environment, not from a global variable.
(type_decl::{get_void_type_decl,
get_variadic_parameter_type_decl}): Remove.
(pointer_type_def::pointer_type_def): Adjust call to type_or_void.
(reference_type_def::reference_type_def): Likewise.
(function_decl::parameter::get_pretty_representation): Get the
variadic parameter type decl from the environment.
(class_decl::priv::classes_being_compared_): Remove static data
member.
(class_decl::priv::{mark_as_being_compared,
unmark_as_being_compared, comparison_started): Use the "classes
being compared" map from the environment.
(class_decl::base_spec::get_hash): Adjust.
(keep_type_alive): Get the alive types array from the environment)
not from a global variable anymore.
(get_next_string): Put the counter in thread-local storage.
* src/abg-hash.cc (scope_decl::hash::operator())
(function_decl::hash::operator()): Do not handle caching (here).
* include/abg-corpus.h (corpus::{g,s}et_environment): Declare new
accessors.
* src/abg-corpus.cc (corpus::priv::env): New data member.
(corpus::priv::priv): Initialize it.
(corpus::corpus): Take an environment in parameter.
(corpus::{g,s}et_environment): Define new member functions
(corpus::add): Set the environment of the newly added translation
unit, if it's not set already set. In any case, assert that the
translation unit must use the same environment as the corpus.
* include/abg-dwarf-reader.h (create_read_context)
(read_corpus_from_elf): Take an environment parameter.
({s,g}et_debug_info_root_path, {s,g}et_environment): Declare new
functions.
* src/abg-dwarf-reader.cc (read_context::{env_,
offline_callbacks_}): New data members.
(read_context::read_context): Initialize them.
(read_context::clear_per_translation_unit_data): Do not touch the
void type declaration, it doesn't belong to the translation unit.
(read_context::{env, offline_callbacks}): New accessors.
(read_context::{create_default_dwfl}): New member function.
(read_context::dwfl_handle): Add a setter overload.
({s,g}et_debug_info_root_path): Define new accessors.
(create_default_dwfl, create_dwfl_sptr, create_default_dwfl_sptr):
Remove these.
(build_translation_unit_and_add_to_ir): Adjust to pass the
environment to the newly created translation unit.
(build_function_decl): Adjust to pass the environment to the
created function and parameter types. Get variadic parameter type
node from the current environment, not from a global variable.
And do not try to canonicalize function types here.
(read_debug_info_into_corpus): Set the environment of the newly
created corpus.
(build_ir_node_for_void_type): Get the void type node from the
current environment, rather than from a global variable.
(create_read_context): Take the environment in parameter.
Create the default dwarf front end library handle using the new
member function of the read context. Set the current environment
used by the reader.
(read_corpus_from_elf): Take an environment in
parameter. Overhaul. This is now simpler.
(has_alt_debug_info): Adjust the call to create_read_context() to
make it pass an empty environment.
* include/abg-fwd.h (class environment): Forward declare.
* include/abg-reader.h (read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream)
(read_corpus_from_native_xml): Take an environment in parameter.
* src/abg-reader.cc (read_context::m_env): New data member.
(read_context::read_context): Initialize it.
(read_context::{get_environment, set_environment}): New data
member.
(read_translation_unit): Set environment of the new translation
unit.
(read_corpus_from_input): Set the environment of the new corpus.
(read_translation_unit_from_file)
(read_translation_unit_from_buffer)
(read_translation_unit_from_istream, read_corpus_from_native_xml):
Take an environment in parameter.
(build_function_parameter): Get variadic parameter type from the environment.
* src/abg-comparison.cc (compute_diff): Add asserts in all the
overloads to ensure that the artifact being compared come from the
same environment.
* tests/print-diff-tree.cc (main): Create an env for the ABI
artifacts to use.
* tests/test-abidiff.cc (main): Likewise.
* tests/test-diff-dwarf.cc (main): Likewise.
* tests/test-ir-walker.cc (main): Likewise.
* tests/test-read-dwarf.cc (main): Likewise.
* tests/test-read-write.cc (main): Likewise.
* tools/abicompat.cc (main): Likewise.
* tools/abidiff.cc (main): Likewise.
* tools/abidw.cc (main): Likewise.
* tools/abilint.cc (main): Likewise.
* tools/abipkgdiff.cc (main): Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-07 20:27:50 +00:00
|
|
|
env.get(),
|
2015-07-08 12:40:51 +00:00
|
|
|
/*load_all_types=*/false,
|
|
|
|
status);
|
2014-03-21 14:15:02 +00:00
|
|
|
|
|
|
|
if (!corp0)
|
|
|
|
{
|
|
|
|
cerr << "failed to read " << in_elfv0_path << "\n";
|
|
|
|
is_ok = false;
|
|
|
|
continue;
|
|
|
|
}
|
2015-07-08 12:40:51 +00:00
|
|
|
|
2014-03-21 14:15:02 +00:00
|
|
|
if (!corp1)
|
|
|
|
{
|
|
|
|
cerr << "failed to read " << in_elfv1_path << "\n";
|
|
|
|
is_ok = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
corp0->set_path(s->in_elfv0_path);
|
|
|
|
corp1->set_path(s->in_elfv1_path);
|
|
|
|
|
|
|
|
corpus_diff_sptr d = compute_diff(corp0, corp1);
|
|
|
|
if (!d)
|
|
|
|
{
|
|
|
|
cerr << "failed to compute diff\n";
|
|
|
|
is_ok = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
ref_diff_report_path = get_src_dir() + "/tests/" + s->in_report_path;
|
|
|
|
out_diff_report_path = get_build_dir() + "/tests/" + s->out_report_path;
|
|
|
|
|
2014-11-05 09:08:33 +00:00
|
|
|
ofstream of(out_diff_report_path.c_str(), std::ios_base::trunc);
|
2014-03-21 14:15:02 +00:00
|
|
|
if (!of.is_open())
|
|
|
|
{
|
|
|
|
cerr << "failed to read " << out_diff_report_path << "\n";
|
|
|
|
is_ok = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-02-05 08:44:00 +00:00
|
|
|
if (d->has_changes())
|
Support comparing symbols not referenced by debug info
* doc/manuals/abidiff.rst: Adjust intro to mention that w/o debug
info, abidiff now works but just report about added/removed
symbols. Add documentation about the new
--no-unreferenced-symbols option.
* include/abg-comparison.h (string_elf_symbol_map): New typedef.
(diff_context::show_symbols_unreferenced_by_debug_info): Declare
new accessors.
* src/abg-comparison.cc
(diff_context::priv::show_syms_unreferenced_by_di_): New data
member.
(diff_context::priv::priv): Adjust.
(diff_context::show_symbols_unreferenced_by_debug_info): Implement
these accessors.
(corpus_diff::priv::{unrefed_fn_syms_edit_script_,
unrefed_var_syms_edit_script_, added_unrefed_fn_syms_,
deleted_unrefed_fn_syms_, added_unrefed_var_syms_,
deleted_unrefed_var_syms_}): New data members.
(corpus_diff::priv::diff_stats::{num_func_syms_removed,
num_func_syms_added, num_var_syms_removed, num_var_syms_added}):
New data members.
(corpus_diff::priv::diff_stats::diff_stats): Adjust.
(corpus_diff::ensure_lookup_tables_populated): Populate lookup
tables for added/removed symbols that are not referenced by any
debug info.
(corpus_diff::priv::apply_filters_and_compute_diff_stats): Compute
stats for the added/removed symbols not referenced by any debug
info.
(corpus_diff::priv::emit_diff_stats): Emit stats about
added/removed symbols that are not referenced by any debug info.
(corpus_diff::length): Adjust to take in account added/removed
symbols not referenced by any debug info.
(show_linkage_name_and_aliases): New static function.
(corpus_diff::report): When emitting a symbol name, emit its
version too, and tell if it aliases other symbols. Avoid emitted
extra new lines. Report added/removed symbols not referenced by
any debug info.
(compute_diff): In the overload for corpus_sptr, compute the diffs
for symbols not referenced by debug info.
* include/abg-corpus.h
(corpus::get_unreferenced_{function,variable}_symbols): Declare
new member functions.
* src/abg-corpus.cc (corpus_priv::{unrefed_fun_symbols,
unrefed_var_symbols}): New data members.
(corpus_priv::build_unreferenced_symbols_tables): Define new
member function.
(struct comp_elf_symbols_functor): New functor.
(corpus::is_empty): Adjust to take in account added/removed
symbols not referenced by debug info.
(corpus::{get_unreferenced_function_symbols,
corpus::get_unreferenced_variable_symbols}): Define these
accessors.
* include/abg-dwarf-reader.h (enum status): Transform this into
bitfields. Add a STATUS_UNKNOWN value that has the value 0.
(operator|(status, status), operator&(status, status))
(operator|=(status&, status), operator&=(status, status)): New
bit-wise operators to manipulate instances of the status bit-field.
* src/abg-dwarf-reader.cc (get_version_for_symbol): Fix this to
avoid returning garbage version sometimes.
(read_debug_info_into_corpus): Fix this to return a non-null but
empty corpus_sptr when there is no debug info available.
(operator|(status, status), operator&(status, status))
(operator|=(status&, status), operator&=(status, status)): Define
these new bitwise operators to manipulate instances of the status
bit-field.
(read_corpus_from_elf): Now that the abigail::dwarf_reader::status
is a bit-field, set it to reflect if debug info and/or symbol
tables have been found. Do not bail out if debug info hasn't been
found. Rather, keep going, and go look for symbols-only; this is
a kind of operating in degraded mode.
* include/abg-ir.h (elf_symbol::get_aliases_id_string): Add a flag
that says if the current instance of elf_symbol should be included
in the list of aliases or not.
* src/abg-ir.cc (elf_symbol::get_aliases_id_string): Define it.
* tests/data/test-diff-dwarf/test16-syms-only-v{0,1}.o: New test
input.
* tools/abidiff.cc
(options::show_symbols_not_referenced_by_debug_info): New data
member.
(options:options): Adjust.
(display_usage): Add an info string for the new
--no-unreferenced-symbols command line option.
(parse_command_line): Parse the new --no-unreferenced-symbols
command line.
(set_diff_context_from_opts): Set the diff_context according to
the presence of --no-unreferenced-symbols.
(main): Adjust for the fact that abigail::dwarf_reader::status is
now a bit-field.
* tools/abilint.cc (main): Adjust for the fact that
abigail::dwarf_reader::status is now a bit-field..
():
* tests/data/test-diff-dwarf/test16-syms-only-report.txt: New test
reference output.
* tests/data/test-diff-dwarf/test16-syms-only-v{0,1}.cc: Source code
for new test input.
* tests/data/test-diff-dwarf/test17-non-refed-syms-v{0,1}.o: New
test input.
* tests/data/test-diff-dwarf/test17-non-refed-syms-v{0,1}.cc: New
source code for test input.
* tests/data/test-diff-dwarf/libtest18-alias-sym-v{0,1}.so: New
test input.
* tests/data/test-diff-dwarf/test18-alias-sym-report-0.txt:
Reference output for new test input.
* tests/data/test-diff-dwarf/test18-alias-sym-v{0,1}.cc: Source
code for new test input.
* tests/data/test-diff-dwarf/test18-alias-sym-version-script:
Source code for new test input.
* tests/Makefile.am: Add the new test materials to the source
distribution.
* tests/test-diff-dwarf.cc(in_out_specs): Add the new input tests
above to the array of tests to run by this harness.
(main): Emit empty reports for empty resulting diffs.
* tests/data/test-diff-dwarf/test{0,8,9,12,14-inline-report,}-report.txt:
Adjust.
* tests/data/test-diff-filter/test{0,01,2,4,5,7,8,9,10,12,13,15-0,15-1}-report.txt:
Likewise.
* tests/data/test-diff-filter/test{19-enum,20-inline,}-report-0.txt:
Likewise.
* tests/data/test-diff-suppr/test0-type-suppr-report-{1,2}.txt:
Likewise.
* tests/data/test-diff-suppr/test{1,2}-typedef-suppr-report-1.txt:
Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-22 16:05:31 +00:00
|
|
|
d->report(of);
|
2014-03-21 14:15:02 +00:00
|
|
|
of.close();
|
|
|
|
|
|
|
|
string cmd =
|
|
|
|
"diff -u " + ref_diff_report_path + " " + out_diff_report_path;
|
|
|
|
if (system(cmd.c_str()))
|
|
|
|
is_ok = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !is_ok;
|
|
|
|
}
|