mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-15 22:44:41 +00:00
84fc161a0b
Commit4252dfd6
added code to allow the ABI write/reread and compare phases of the tests to be skipped in the case that no ABI files are given for comparison. Unfortunately, the new code skipped those phases unconditionally. This patch changes the in_abi_path and out_abi_path values used in in_out_specs used to trigger the early termination from "" to NULL and updates the conditional logic checking them. Several subsequent commits which affect ABI output were missing these changes to the test data files. This change fixes the following list of commits.4252dfd6
dwarf-reader: handle symtab.section_header.sh_entsize == 04457c10e
dwarf-reader: handle binaries with missing symtab34e867e7
dwarf-reader: remove superfluous ABG_ASSERT2d5389f2
Fix size calculations for multidimensional arrays.246ca200
corpus/writer: sort emitted translation units by path namee8bf5b80
Bug 25989 - type_topo_comp doesn't meet irreflexive requirements Finally, this commit also corrects some bad code formatting. * tests/test-read-dwarf.cc (in_out_specs): Use NULL instead of empty ABI paths for test25, test26 and test27. (perform): Check members of spec, rather than locals with same name, when deciding to terminate testing early; fix some code whitespace. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Update multidimensional array sizes. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Ditto. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Ditto. * tests/data/test-read-dwarf/test7.so.abi: Ditto. * tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi: Update following translation unit ordering change. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Ditto. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Ditto. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Ditto. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Ditto. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Ditto. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Ditto. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Ditto. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Ditto. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Ditto. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Ditto. * tests/data/test-read-dwarf/PR25007-sdhci.ko.abi: Update following code changes affecting ordering of some ABI elements. * tests/data/test-read-dwarf/test16-pr18904.so.abi Reviewed-by: Matthias Maennich <maennich@google.com> Tested-by: Matthias Maennich <maennich@google.com> Signed-off-by: Giuliano Procida <gprocida@google.com>
579 lines
16 KiB
C++
579 lines
16 KiB
C++
// -*- Mode: C++ -*-
|
|
//
|
|
// Copyright (C) 2013-2020 Red Hat, Inc.
|
|
//
|
|
// 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 <vector>
|
|
#include <cstdlib>
|
|
#include "abg-ir.h"
|
|
#include "abg-dwarf-reader.h"
|
|
#include "abg-workers.h"
|
|
#include "abg-writer.h"
|
|
#include "abg-tools-utils.h"
|
|
#include "test-utils.h"
|
|
|
|
using std::vector;
|
|
using std::string;
|
|
using std::ofstream;
|
|
using std::cerr;
|
|
using abg_compat::dynamic_pointer_cast;
|
|
using abigail::tests::get_build_dir;
|
|
using abigail::dwarf_reader::read_corpus_from_elf;
|
|
using abigail::dwarf_reader::read_context;
|
|
using abigail::dwarf_reader::read_context_sptr;
|
|
using abigail::dwarf_reader::create_read_context;
|
|
using abigail::xml_writer::SEQUENCE_TYPE_ID_STYLE;
|
|
using abigail::xml_writer::HASH_TYPE_ID_STYLE;
|
|
using abigail::xml_writer::create_write_context;
|
|
using abigail::xml_writer::set_type_id_style;
|
|
using abigail::xml_writer::type_id_style_kind;
|
|
using abigail::xml_writer::write_context_sptr;
|
|
using abigail::xml_writer::write_corpus;
|
|
|
|
/// 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_suppr_spec_path;
|
|
type_id_style_kind type_id_style;
|
|
const char* in_abi_path;
|
|
const char* out_abi_path;
|
|
};// end struct InOutSpec
|
|
|
|
|
|
InOutSpec in_out_specs[] =
|
|
{
|
|
{
|
|
"data/test-read-dwarf/test0",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test0.abi",
|
|
"output/test-read-dwarf/test0.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test0",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test0.hash.abi",
|
|
"output/test-read-dwarf/test0.hash.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test1",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test1.abi",
|
|
"output/test-read-dwarf/test1.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test1",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test1.hash.abi",
|
|
"output/test-read-dwarf/test1.hash.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test2.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test2.so.abi",
|
|
"output/test-read-dwarf/test2.so.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test2.so",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test2.so.hash.abi",
|
|
"output/test-read-dwarf/test2.so.hash.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test3.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test3.so.abi",
|
|
"output/test-read-dwarf/test3.so.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test3.so",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test3.so.hash.abi",
|
|
"output/test-read-dwarf/test3.so.hash.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test4.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test4.so.abi",
|
|
"output/test-read-dwarf/test4.so.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test4.so",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test4.so.hash.abi",
|
|
"output/test-read-dwarf/test4.so.hash.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test5.o",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test5.o.abi",
|
|
"output/test-read-dwarf/test5.o.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test5.o",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test5.o.hash.abi",
|
|
"output/test-read-dwarf/test5.o.hash.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test6.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test6.so.abi",
|
|
"output/test-read-dwarf/test6.so.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test6.so",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test6.so.hash.abi",
|
|
"output/test-read-dwarf/test6.so.hash.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test7.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test7.so.abi",
|
|
"output/test-read-dwarf/test7.so.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test7.so",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test7.so.hash.abi",
|
|
"output/test-read-dwarf/test7.so.hash.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test8-qualified-this-pointer.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test8-qualified-this-pointer.so.abi",
|
|
"output/test-read-dwarf/test8-qualified-this-pointer.so.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test8-qualified-this-pointer.so",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi",
|
|
"output/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test9-pr18818-clang.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"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",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test10-pr18818-gcc.so.abi",
|
|
"output/test-read-dwarf/test10-pr18818-gcc.so.abi"
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test11-pr18828.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test11-pr18828.so.abi",
|
|
"output/test-read-dwarf/test11-pr18828.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test12-pr18844.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test12-pr18844.so.abi",
|
|
"output/test-read-dwarf/test12-pr18844.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test13-pr18894.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test13-pr18894.so.abi",
|
|
"output/test-read-dwarf/test13-pr18894.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test14-pr18893.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test14-pr18893.so.abi",
|
|
"output/test-read-dwarf/test14-pr18893.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test15-pr18892.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test15-pr18892.so.abi",
|
|
"output/test-read-dwarf/test15-pr18892.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test16-pr18904.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test16-pr18904.so.abi",
|
|
"output/test-read-dwarf/test16-pr18904.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test17-pr19027.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test17-pr19027.so.abi",
|
|
"output/test-read-dwarf/test17-pr19027.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
|
|
"output/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
|
|
"output/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi",
|
|
"output/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test21-pr19092.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/test21-pr19092.so.abi",
|
|
"output/test-read-dwarf/test21-pr19092.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"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",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/libtest23.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/libtest23.so.abi",
|
|
"output/test-read-dwarf/libtest23.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/libtest24-drop-fns.so",
|
|
"data/test-read-dwarf/test24-drop-fns-0.suppr",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/libtest24-drop-fns.so.abi",
|
|
"output/test-read-dwarf/libtest24-drop-fns.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/libtest24-drop-fns.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/libtest24-drop-fns-2.so.abi",
|
|
"output/test-read-dwarf/libtest24-drop-fns-2.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/PR22015-libboost_iostreams.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/PR22015-libboost_iostreams.so.abi",
|
|
"output/test-read-dwarf/PR22015-libboost_iostreams.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/PR22122-libftdc.so",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/PR22122-libftdc.so.abi",
|
|
"output/test-read-dwarf/PR22122-libftdc.so.abi",
|
|
},
|
|
{
|
|
"data/test-read-dwarf/PR24378-fn-is-not-scope.o",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/PR24378-fn-is-not-scope.abi",
|
|
"output/test-read-dwarf/PR24378-fn-is-not-scope.abi",
|
|
},
|
|
#if defined(HAVE_R_AARCH64_ABS64_MACRO) && defined(HAVE_R_AARCH64_PREL32_MACRO)
|
|
{
|
|
"data/test-read-dwarf/PR25007-sdhci.ko",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/PR25007-sdhci.ko.abi",
|
|
"output/test-read-dwarf/PR25007-sdhci.ko.abi",
|
|
},
|
|
#endif
|
|
#if defined HAVE_DW_FORM_strx
|
|
{
|
|
"data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi",
|
|
"output/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi",
|
|
},
|
|
#endif
|
|
{
|
|
"data/test-read-dwarf/test25-bogus-binary.elf",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
NULL,
|
|
NULL,
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test26-bogus-binary.elf",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
NULL,
|
|
NULL,
|
|
},
|
|
{
|
|
"data/test-read-dwarf/test27-bogus-binary.elf",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
NULL,
|
|
NULL,
|
|
},
|
|
// This should be the last entry.
|
|
{NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL}
|
|
};
|
|
|
|
using abigail::suppr::suppression_sptr;
|
|
using abigail::suppr::suppressions_type;
|
|
using abigail::suppr::read_suppressions;
|
|
|
|
/// Set the suppression specification to use when reading the ELF binary.
|
|
///
|
|
/// @param read_ctxt the context used to read the ELF binary.
|
|
///
|
|
/// @param path the path to the suppression specification to read.
|
|
static void
|
|
set_suppressions(read_context& read_ctxt, const string& path)
|
|
{
|
|
suppressions_type supprs;
|
|
read_suppressions(path, supprs);
|
|
add_read_context_suppressions(read_ctxt, supprs);
|
|
}
|
|
|
|
/// The task that peforms the tests.
|
|
struct test_task : public abigail::workers::task
|
|
{
|
|
bool is_ok;
|
|
InOutSpec spec;
|
|
string error_message;
|
|
string out_abi_base;
|
|
string in_elf_base;
|
|
string in_abi_base;
|
|
|
|
test_task(const InOutSpec &s,
|
|
string& a_out_abi_base,
|
|
string& a_in_elf_base,
|
|
string& a_in_abi_base)
|
|
: is_ok(true),
|
|
spec(s),
|
|
out_abi_base(a_out_abi_base),
|
|
in_elf_base(a_in_elf_base),
|
|
in_abi_base(a_in_abi_base)
|
|
{}
|
|
|
|
/// The actual test.
|
|
///
|
|
/// This reads the corpus into memory, saves it to disk, loads it
|
|
/// again and compares the new in-memory representation against the
|
|
/// saved one.
|
|
virtual void
|
|
perform()
|
|
{
|
|
string in_elf_path, in_abi_path, in_suppr_spec_path, out_abi_path;
|
|
abigail::ir::environment_sptr env;
|
|
|
|
in_elf_path = in_elf_base + spec.in_elf_path;
|
|
if (spec.in_suppr_spec_path)
|
|
in_suppr_spec_path = in_elf_base + spec.in_suppr_spec_path;
|
|
else
|
|
in_suppr_spec_path.clear();
|
|
|
|
env.reset(new abigail::ir::environment);
|
|
abigail::dwarf_reader::status status =
|
|
abigail::dwarf_reader::STATUS_UNKNOWN;
|
|
vector<char**> di_roots;
|
|
ABG_ASSERT(abigail::tools_utils::file_exists(in_elf_path));
|
|
read_context_sptr ctxt = create_read_context(in_elf_path,
|
|
di_roots,
|
|
env.get());
|
|
ABG_ASSERT(ctxt);
|
|
if (!in_suppr_spec_path.empty())
|
|
set_suppressions(*ctxt, in_suppr_spec_path);
|
|
|
|
abigail::corpus_sptr corp = read_corpus_from_elf(*ctxt, status);
|
|
// if there is no output and no input, assume that we do not care about the
|
|
// actual read result, just that it succeeded.
|
|
if (!spec.in_abi_path && !spec.out_abi_path)
|
|
{
|
|
// Phew! we made it here and we did not crash! yay!
|
|
return;
|
|
}
|
|
if (!corp)
|
|
{
|
|
error_message = string("failed to read ") + in_elf_path + "\n";
|
|
is_ok = false;
|
|
return;
|
|
}
|
|
corp->set_path(spec.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("");
|
|
|
|
out_abi_path = out_abi_base + spec.out_abi_path;
|
|
if (!abigail::tools_utils::ensure_parent_dir_created(out_abi_path))
|
|
{
|
|
error_message =
|
|
string("Could not create parent directory for ") + out_abi_path;
|
|
is_ok = false;
|
|
return;
|
|
}
|
|
|
|
ofstream of(out_abi_path.c_str(), std::ios_base::trunc);
|
|
if (!of.is_open())
|
|
{
|
|
error_message = string("failed to read ") + out_abi_path + "\n";
|
|
is_ok = false;
|
|
return;
|
|
}
|
|
write_context_sptr write_ctxt
|
|
= create_write_context(corp->get_environment(), of);
|
|
set_type_id_style(*write_ctxt, spec.type_id_style);
|
|
is_ok = write_corpus(*write_ctxt, corp, /*indent=*/0);
|
|
of.close();
|
|
|
|
string abidw = string(get_build_dir()) + "/tools/abidw";
|
|
string cmd = abidw + " --abidiff " + in_elf_path;
|
|
if (system(cmd.c_str()))
|
|
{
|
|
error_message = string("ABIs differ:\n")
|
|
+ in_elf_path
|
|
+ "\nand:\n"
|
|
+ out_abi_path
|
|
+ "\n";
|
|
is_ok = false;
|
|
}
|
|
|
|
in_abi_path = in_abi_base + spec.in_abi_path;
|
|
cmd = "diff -u " + in_abi_path + " " + out_abi_path;
|
|
if (system(cmd.c_str()))
|
|
is_ok = false;
|
|
}
|
|
}; // end struct test_task
|
|
|
|
typedef shared_ptr<test_task> test_task_sptr;
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
bool no_parallel = false;
|
|
|
|
if (argc == 2)
|
|
{
|
|
if (argv[1] == string("--no-parallel"))
|
|
no_parallel = true;
|
|
else
|
|
{
|
|
cerr << "unrecognized option\n";
|
|
cerr << "usage: " << argv[0] << " [--no-parallel]\n" ;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/// Create a task queue. The max number of worker threads of the
|
|
/// queue is the number of the concurrent threads supported by the
|
|
/// processor of the machine this code runs on. But if
|
|
/// --no-parallel was provided then the number of worker threads
|
|
/// equals 1.
|
|
const size_t num_tests = sizeof(in_out_specs) / sizeof (InOutSpec) - 1;
|
|
size_t num_workers = (no_parallel
|
|
? 1
|
|
: std::min(abigail::workers::get_number_of_threads(),
|
|
num_tests));
|
|
abigail::workers::queue task_queue(num_workers);
|
|
bool is_ok = true;
|
|
|
|
string out_abi_base = string(get_build_dir()) + "/tests/";
|
|
string in_elf_base = string(abigail::tests::get_src_dir()) + "/tests/";
|
|
string in_abi_base = in_elf_base;
|
|
|
|
for (InOutSpec *s = in_out_specs; s->in_elf_path; ++s)
|
|
{
|
|
test_task_sptr t(new test_task(*s, out_abi_base,
|
|
in_elf_base,
|
|
in_abi_base));
|
|
ABG_ASSERT(task_queue.schedule_task(t));
|
|
}
|
|
|
|
/// Wait for all worker threads to finish their job, and wind down.
|
|
task_queue.wait_for_workers_to_complete();
|
|
|
|
// Now walk the results and print whatever error messages need to be
|
|
// printed.
|
|
|
|
const vector<abigail::workers::task_sptr>& completed_tasks =
|
|
task_queue.get_completed_tasks();
|
|
|
|
ABG_ASSERT(completed_tasks.size() == num_tests);
|
|
|
|
for (vector<abigail::workers::task_sptr>::const_iterator ti =
|
|
completed_tasks.begin();
|
|
ti != completed_tasks.end();
|
|
++ti)
|
|
{
|
|
test_task_sptr t = dynamic_pointer_cast<test_task>(*ti);
|
|
if (!t->is_ok)
|
|
{
|
|
is_ok = false;
|
|
if (!t->error_message.empty())
|
|
cerr << t->error_message << '\n';
|
|
}
|
|
}
|
|
|
|
return !is_ok;
|
|
}
|