2014-01-07 14:34:42 +00:00
|
|
|
// -*- Mode: C++ -*-
|
|
|
|
//
|
2016-01-15 12:34:16 +00:00
|
|
|
// Copyright (C) 2013-2016 Red Hat, Inc.
|
2014-01-07 14:34:42 +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 read ELF binaries containing DWARF, save them in XML corpus
|
|
|
|
/// files and diff the corpus files against reference XML corpus
|
|
|
|
/// files.
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <fstream>
|
|
|
|
#include <iostream>
|
|
|
|
#include <cstdlib>
|
2015-10-06 12:35:14 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <pthread.h>
|
2014-01-07 14:34:42 +00:00
|
|
|
#include "abg-ir.h"
|
|
|
|
#include "abg-dwarf-reader.h"
|
|
|
|
#include "abg-writer.h"
|
|
|
|
#include "abg-tools-utils.h"
|
|
|
|
#include "test-utils.h"
|
|
|
|
|
|
|
|
using std::string;
|
|
|
|
using std::ofstream;
|
|
|
|
using std::cerr;
|
2015-08-29 11:10:25 +00:00
|
|
|
using abigail::tests::get_build_dir;
|
2015-10-06 12:35:14 +00:00
|
|
|
using abigail::dwarf_reader::read_corpus_from_elf;
|
2014-01-07 14:34:42 +00:00
|
|
|
|
|
|
|
/// This is an aggregate that specifies where a test shall get its
|
|
|
|
/// input from, and where it shall write its ouput to.
|
|
|
|
struct InOutSpec
|
|
|
|
{
|
|
|
|
const char* in_elf_path;
|
|
|
|
const char* in_abi_path;
|
|
|
|
const char* out_abi_path;
|
|
|
|
};// end struct InOutSpec
|
|
|
|
|
|
|
|
|
|
|
|
InOutSpec in_out_specs[] =
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test0",
|
|
|
|
"data/test-read-dwarf/test0.abi",
|
|
|
|
"output/test-read-dwarf/test0.abi"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test1",
|
|
|
|
"data/test-read-dwarf/test1.abi",
|
|
|
|
"output/test-read-dwarf/test1.abi"
|
|
|
|
},
|
Initial support for DW_TAG_partial_unit
* src/abg-dwarf-reader.cc (read_context::cur_tu_die_): New member.
(read_context::read_context): Initialize the new member.
(read_context::cur_tu_die): New accessors.
(find_last_import_unit_point_before_die): New static function.
(get_parent_die): Take a logical current die offset parameter. If
the die we want the parent for is a partial unit, then find the
last DW_TAG_imported_unit that imports that partial unit before
the logical current die and return the parent of that
DW_TAG_imported_unit die.
(get_scope_for_die): Take a logical current die offset parameter.
Adjust.
(build_translation_unit_and_add_to_ir): Set/unset the current
translation unit DIE in the context. Adjust.
(build_namespace_decl_and_add_to_ir)
(build_class_type_and_add_to_ir, build_qualified_type)
(build_pointer_type_def, build_reference_type, build_typedef_type)
(build_var_decl, build_function_decl, build_ir_node_from_die):
Take a logical current die offset parameter. Adjust.
(build_corpus): Accept that we can have DIE that are not
DW_TAG_compile_unit at the top level, because, well, we can now
have DW_TAG_partial_unit too.
* tests/data/test-read-dwarf/test2-{0,1}.cc: New test source
files.
* tests/data/test-read-dwarf/test2.h: Likewise.
* tests/data/test-read-dwarf/test2.so: New input binary to read.
* tests/data/test-read-dwarf/test2.so.abi: New reference test to
compare against.
* tests/test-read-dwarf.cc: Adjust to launch the new test.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-19 15:26:40 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test2.so",
|
|
|
|
"data/test-read-dwarf/test2.so.abi",
|
|
|
|
"output/test-read-dwarf/test2.so.abi"
|
|
|
|
},
|
2014-06-19 06:43:54 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test3.so",
|
|
|
|
"data/test-read-dwarf/test3.so.abi",
|
|
|
|
"output/test-read-dwarf/test3.so.abi"
|
|
|
|
},
|
2014-06-22 22:31:19 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test4.so",
|
|
|
|
"data/test-read-dwarf/test4.so.abi",
|
|
|
|
"output/test-read-dwarf/test4.so.abi"
|
|
|
|
},
|
2014-06-23 15:24:54 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test5.o",
|
|
|
|
"data/test-read-dwarf/test5.o.abi",
|
|
|
|
"output/test-read-dwarf/test5.o.abi"
|
|
|
|
},
|
2014-07-01 11:57:00 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test6.so",
|
|
|
|
"data/test-read-dwarf/test6.so.abi",
|
|
|
|
"output/test-read-dwarf/test6.so.abi"
|
|
|
|
},
|
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-read-dwarf/test7.so",
|
|
|
|
"data/test-read-dwarf/test7.so.abi",
|
|
|
|
"output/test-read-dwarf/test7.so.abi"
|
|
|
|
},
|
2014-10-16 21:32:08 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test8-qualified-this-pointer.so",
|
|
|
|
"data/test-read-dwarf/test8-qualified-this-pointer.so.abi",
|
|
|
|
"output/test-read-dwarf/test8-qualified-this-pointer.so.abi"
|
|
|
|
},
|
2015-08-12 21:55:18 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test9-pr18818-clang.so",
|
|
|
|
"data/test-read-dwarf/test9-pr18818-clang.so.abi",
|
|
|
|
"output/test-read-dwarf/test9-pr18818-clang.so.abi",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test10-pr18818-gcc.so",
|
|
|
|
"data/test-read-dwarf/test10-pr18818-gcc.so.abi",
|
|
|
|
"output/test-read-dwarf/test10-pr18818-gcc.so.abi",
|
|
|
|
},
|
2015-08-14 22:10:26 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test11-pr18828.so",
|
|
|
|
"data/test-read-dwarf/test11-pr18828.so.abi",
|
2015-08-18 10:31:45 +00:00
|
|
|
"output/test-read-dwarf/test11-pr18828.so.abi",
|
2015-08-14 22:10:26 +00:00
|
|
|
},
|
2015-08-18 10:33:57 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test12-pr18844.so",
|
|
|
|
"data/test-read-dwarf/test12-pr18844.so.abi",
|
|
|
|
"output/test-read-dwarf/test12-pr18844.so.abi",
|
|
|
|
},
|
2015-08-29 15:17:48 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test13-pr18894.so",
|
|
|
|
"data/test-read-dwarf/test13-pr18894.so.abi",
|
|
|
|
"output/test-read-dwarf/test13-pr18894.so.abi",
|
2015-08-30 14:19:50 +00:00
|
|
|
},
|
2015-08-30 15:56:19 +00:00
|
|
|
{
|
2015-08-30 14:19:50 +00:00
|
|
|
"data/test-read-dwarf/test14-pr18893.so",
|
|
|
|
"data/test-read-dwarf/test14-pr18893.so.abi",
|
|
|
|
"output/test-read-dwarf/test14-pr18893.so.abi",
|
2015-08-29 15:17:48 +00:00
|
|
|
},
|
2015-08-30 15:56:19 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test15-pr18892.so",
|
|
|
|
"data/test-read-dwarf/test15-pr18892.so.abi",
|
|
|
|
"output/test-read-dwarf/test15-pr18892.so.abi",
|
|
|
|
},
|
2015-09-02 11:41:34 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test16-pr18904.so",
|
|
|
|
"data/test-read-dwarf/test16-pr18904.so.abi",
|
|
|
|
"output/test-read-dwarf/test16-pr18904.so.abi",
|
|
|
|
},
|
2015-10-01 09:06:15 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test17-pr19027.so",
|
|
|
|
"data/test-read-dwarf/test17-pr19027.so.abi",
|
|
|
|
"output/test-read-dwarf/test17-pr19027.so.abi",
|
|
|
|
},
|
2015-10-06 10:01:20 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so",
|
|
|
|
"data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
|
|
|
|
"output/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
|
|
|
|
},
|
2015-10-06 22:08:46 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so",
|
|
|
|
"data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
|
|
|
|
"output/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
|
|
|
|
},
|
Bug 19025 - abixml writer forgets to emit some member types
When a member type (a type that is a member of a class) M is
referenced by some types emitted by abixml, but the context of M (the
class type which M is a member of) is not itself referenced by any ABI
artifact, then abixml forgets to emit the context of M and thus M
itself.
With this patch, when the abixml writer has emitted almost all ABI
artifacts for the current translation unit, it looks for types that
have been referenced by the emitted ABI artifacts, but that haven't
been emitted themselves.
It then emits those referenced-but-not-emitted types, and makes sure
their contexts are emitted as well.
* include/abg-fwd.h (is_namespace): Fix prototype.
* src/abg-writer.cc (struct type_ptr_comp_functor): New internal
type.
(sort_type_ptr_map): New static function.
(write_context::m_referenced_types_map): Renamed
m_referenced_fntypes_map data member into this.
(write_context::get_referenced_types): New member function.
(write_context::record_type_as_referenced): Renamed
record_fntype_as_referenced member function into this. Adjust.
(write_context::type_is_referenced): Renamed fntype_is_referenced
into this.
(write_context::clear_referenced_types_map): Renamed
clear_referenced_fntypes_map member function into this. Adjust.
(write_decl_in_scope): New static function.
(write_translation_unit): Use it here to emit types that are
referenced by other types in the TU, but that are not emitted.
Adjust.
(write_pointer_type_def, write_reference_type_def)
(write_typedef_decl): Record the underlying types referenced by
the emitted types as being, well, referenced.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so:
New test binary input.
* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
New reference output of the binary input above.
* tests/data/Makefile.am: Add the new test material above to the
source distribution.
* tests/test-read-dwarf.cc (in_out_spec): Add the new test inputs.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
Likewise.
* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-08 10:57:04 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so",
|
|
|
|
"data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi",
|
|
|
|
"output/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi",
|
|
|
|
},
|
2015-10-15 14:06:35 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test21-pr19092.so",
|
|
|
|
"data/test-read-dwarf/test21-pr19092.so.abi",
|
2015-10-17 13:05:41 +00:00
|
|
|
"output/test-read-dwarf/test21-pr19092.so.abi",
|
2015-10-15 14:06:35 +00:00
|
|
|
},
|
2015-10-17 13:03:41 +00:00
|
|
|
{
|
|
|
|
"data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so",
|
|
|
|
"data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi",
|
|
|
|
"output/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi",
|
|
|
|
},
|
2014-01-07 14:34:42 +00:00
|
|
|
// This should be the last entry.
|
|
|
|
{NULL, NULL, NULL}
|
|
|
|
};
|
|
|
|
|
2015-10-06 12:35:14 +00:00
|
|
|
// The global pointer to the testsuite paths.
|
|
|
|
InOutSpec *iospec = in_out_specs;
|
|
|
|
// Lock to help atomically increment iospec.
|
|
|
|
pthread_mutex_t spec_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
pthread_mutex_t write_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
// No lock needed here, since is_ok is only ever re-set to false.
|
|
|
|
bool is_ok = true;
|
2014-01-07 14:34:42 +00:00
|
|
|
|
2015-10-06 12:35:14 +00:00
|
|
|
// These prefixes don't change during the program's lifetime, so
|
|
|
|
// we only get them once.
|
2016-01-15 12:34:16 +00:00
|
|
|
const string out_abi_base = string(get_build_dir()) + "/tests/";
|
|
|
|
const string in_elf_base = string(abigail::tests::get_src_dir()) + "/tests/";
|
2015-10-06 12:35:14 +00:00
|
|
|
const string in_abi_base = in_elf_base;
|
|
|
|
|
|
|
|
void
|
|
|
|
handle_in_out_spec(void)
|
|
|
|
{
|
2014-01-07 14:34:42 +00:00
|
|
|
string in_elf_path, in_abi_path, out_abi_path;
|
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
|
|
|
abigail::ir::environment_sptr env;
|
2015-10-06 12:35:14 +00:00
|
|
|
InOutSpec *s;
|
2014-01-07 14:34:42 +00:00
|
|
|
|
2015-10-06 12:35:14 +00:00
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&spec_lock);
|
|
|
|
if (iospec->in_elf_path)
|
|
|
|
s = iospec++;
|
|
|
|
else
|
|
|
|
s = NULL;
|
|
|
|
pthread_mutex_unlock(&spec_lock);
|
2014-01-07 14:34:42 +00:00
|
|
|
|
2015-10-06 12:35:14 +00:00
|
|
|
if (!s)
|
|
|
|
pthread_exit(NULL);
|
|
|
|
in_elf_path = in_elf_base + s->in_elf_path;
|
|
|
|
env.reset(new abigail::ir::environment);
|
|
|
|
abigail::dwarf_reader::status status =
|
|
|
|
abigail::dwarf_reader::STATUS_UNKNOWN;
|
|
|
|
abigail::corpus_sptr corp =
|
|
|
|
read_corpus_from_elf(in_elf_path,
|
|
|
|
/*debug_info_root_path=*/0,
|
|
|
|
env.get(),
|
|
|
|
/*load_all_types=*/false,
|
|
|
|
status);
|
|
|
|
if (!corp)
|
|
|
|
{
|
|
|
|
cerr << "failed to read " << in_elf_path << "\n";
|
|
|
|
is_ok = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
corp->set_path(s->in_elf_path);
|
|
|
|
// Do not take architecture names in comparison so that these
|
|
|
|
// test input binaries can come from whatever arch the
|
|
|
|
// programmer likes.
|
|
|
|
corp->set_architecture_name("");
|
2014-01-07 14:34:42 +00:00
|
|
|
|
2015-10-06 12:35:14 +00:00
|
|
|
out_abi_path = out_abi_base + s->out_abi_path;
|
|
|
|
if (!abigail::tools_utils::ensure_parent_dir_created(out_abi_path))
|
|
|
|
{
|
|
|
|
cerr << "Could not create parent directory for " << out_abi_path;
|
|
|
|
is_ok = false;
|
|
|
|
exit(1);
|
|
|
|
}
|
2015-08-29 11:10:25 +00:00
|
|
|
|
2015-10-06 12:35:14 +00:00
|
|
|
ofstream of(out_abi_path.c_str(), std::ios_base::trunc);
|
|
|
|
if (!of.is_open())
|
|
|
|
{
|
|
|
|
cerr << "failed to read " << out_abi_path << "\n";
|
|
|
|
is_ok = false;
|
|
|
|
continue;
|
|
|
|
}
|
2015-08-29 11:10:25 +00:00
|
|
|
|
2015-10-06 12:35:14 +00:00
|
|
|
pthread_mutex_lock(&write_lock);
|
|
|
|
is_ok =
|
|
|
|
abigail::xml_writer::write_corpus_to_native_xml(corp,
|
|
|
|
/*indent=*/0,
|
|
|
|
of);
|
|
|
|
pthread_mutex_unlock(&write_lock);
|
|
|
|
of.close();
|
|
|
|
|
2016-01-15 12:34:16 +00:00
|
|
|
string abidw = string(get_build_dir()) + "/tools/abidw";
|
2015-10-17 13:06:57 +00:00
|
|
|
string cmd = abidw + " --abidiff " + in_elf_path;
|
2015-10-06 12:35:14 +00:00
|
|
|
if (system(cmd.c_str()))
|
|
|
|
{
|
|
|
|
cerr << "ABIs differ:\n"
|
|
|
|
<< in_elf_path
|
|
|
|
<< "\nand:\n"
|
|
|
|
<< out_abi_path
|
|
|
|
<< "\n";
|
|
|
|
is_ok = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
in_abi_path = in_abi_base + s->in_abi_path;
|
|
|
|
cmd = "diff -u " + in_abi_path + " " + out_abi_path;
|
|
|
|
if (system(cmd.c_str()))
|
|
|
|
is_ok = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
// Number of currently online processors in the system.
|
|
|
|
size_t nprocs = sysconf(_SC_NPROCESSORS_ONLN);
|
|
|
|
// All the pthread_ts we've created.
|
|
|
|
pthread_t *pthr = new pthread_t[nprocs];
|
|
|
|
|
|
|
|
if (argc == 2)
|
|
|
|
{
|
|
|
|
if (argv[1] == string("--no-parallel"))
|
|
|
|
nprocs = 1;
|
|
|
|
else
|
2015-08-29 11:10:25 +00:00
|
|
|
{
|
2015-10-06 12:35:14 +00:00
|
|
|
cerr << "unrecognized option\n";
|
|
|
|
cerr << "usage: " << argv[0] << " [--no-parallel]\n" ;
|
|
|
|
return 1;
|
2015-08-29 11:10:25 +00:00
|
|
|
}
|
2014-01-07 14:34:42 +00:00
|
|
|
}
|
|
|
|
|
2015-10-06 12:35:14 +00:00
|
|
|
assert(nprocs >= 1);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < nprocs; ++i)
|
|
|
|
pthread_create(&pthr[i], NULL,
|
|
|
|
(void*(*)(void*))handle_in_out_spec,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < nprocs; ++i)
|
|
|
|
pthread_join(pthr[i], NULL);
|
|
|
|
|
|
|
|
delete pthr;
|
|
|
|
|
2014-01-07 14:34:42 +00:00
|
|
|
return !is_ok;
|
|
|
|
}
|