mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-13 21:44:52 +00:00
610d87c29b
In the text below, the term interface means the "declaration of either a function or a global variable". To analyze the compatibility between an application and a dependent library, one has essentially to analyze the interfaces of the application that have undefined symbols (aka undefined interfaces from the application) and see how they relate to the same interfaces coming from the library but with symbols that are defined and exported from the library (aka defined/exported interfaces from the library). An interface that is undefined in the application and defined in the library is an interface that the application consumes from the library. In other words an undefined interface from an application is an interface that the application expects and an interface that is exported by a library is an interface that the library provides. If comparing the expected interface against the provided interface yields a meaningful difference, then that might mean there is an incompatibility between the application and the library on that interface. This patch uses this scheme to re-implement the weak mode of ABI compatibility between an application and a library. The patch adds the concept of undefined functions and variables to the ABI corpus. Then it teaches the DWARF reader how to construct the IR for these undefined interfaces. Then it revisits the weak mode of operation of abicompat to make it compare the interfaces expected from the application against the corresponding interfaces provided by library. The patch also teaches the weak mode abicompat how to detect incompatibilities between the interfaces that plugin expects and the interfaces provided by the application. This patch makes the CTF front-end construct undefined interfaces. A subsequent patch is needed to construct undefined interfaces from the BTF front-end however. * include/abg-corpus.h (corpus::{lookup_variable, get_undefined_functions, get_undefined_variables}): Declare new member functions. (corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns): Make this return a boolean. * include/abg-fe-iface.h (fe_iface::options_type): Add a new load_undefined_interfaces enumerator. (fe_iface::add_fn_to_exported_or_undefined_decls): Rename maybe_add_fn_to_exported_decls into this. (fe_iface::add_var_to_exported_or_undefined_decls): Rename maybe_add_var_to_exported_decls into this. * src/abg-btf-reader.cc (reader::build_ir_node_from_btf_type): Adjust call to maybe_add_fn_to_exported_decls as add_fn_to_exported_or_undefined_decls. Similarly, adjust call to maybe_add_var_to_exported_decls as add_var_to_exported_or_undefined_decls. * src/abg-corpus-priv.h (corpus::priv::undefined_{fns,vars}): Add new member variables. * src/abg-corpus.cc (corpus::exported_decls_builder::maybe_add_{fn,var}_to_exported_fns): Return a bool iff the decl was added to the set of exported decls. (corpus::{lookup_variable, get_undefined_functions, get_undefined_variables}): Define new member functions. (corpus::sort_{functions,variables}): Sort the undefined decls too. * (corpus::lookup_{function,variable}_symbol): Lookup the symbol also among undefined symbols, not just among defined symbols. * src/abg-ctf-reader.cc (reader::process_ctf_archive): Adjust call to maybe_add_fn_to_exported_decls as add_fn_to_exported_or_undefined_decls. Similarly, adjust call to maybe_add_var_to_exported_decls as add_var_to_exported_or_undefined_decls. Also, sort functions & variables in the corpus. * src/abg-dwarf-reader.cc (die_name_and_linkage_name): Define new static function. (reader::fixup_functions_with_no_symbols): Adjust call to maybe_add_fn_to_exported_decls as add_fn_to_exported_or_undefined_decls. (reader::{is_decl_die_with_undefined_symbol, load_undefined_interfaces}): Define new member functions. (build_translation_unit_and_add_to_ir): Analyze DIEs of interfaces that have undefined symbols if we were asked to load undefined interfaces. (variable_is_suppressed): Add a boolean parameter to tell if the var is decl-only. Use that decl-only flag to determine if the variable is suppressed. A non-member decl-only variable won't be suppressed if we were asked to load undefined interfaces. (build_or_get_var_decl_if_not_suppressed): Add a boolean parameter to tell if the var is decl-only. (potential_member_fn_should_be_dropped): A potential non-virtual member function with no symbol is now dropped on the floor regardless of it has a mangled name or not. (build_var_decl): If the var has an undefined symbol, then set that symbol. (build_function_decl): If the function has an undefined symbol, then set that symbol. (build_ir_node_from_die): Add a var or function with undefined symbol to the set of undefined vars or functions of the current corpus. * src/abg-fe-iface.cc (fe_iface::add_fn_to_exported_or_undefined_decls): Renamed fe_iface::maybe_add_fn_to_exported_decls into this. If the function has an undefined symbol then add the function to the set of undefined functions. (fe_iface::add_var_to_exported_or_undefined_decls): Renamed fe_iface::maybe_add_var_to_exported_decls into this. If the variable has an undefined symbol then add the variable to the set of undefined variables. * src/abg-ir.cc (elf_symbol::is_variable): Undefined symbol with type STT_NOTYPE are actually for undefined variables. (maybe_adjust_canonical_type): It's here, after type canonicalization that a member function is added to either the set of defined & exported functions, or to the set of functions with undefined symbols. * src/abg-reader.cc (build_function_decl, build_class_decl) (build_union_decl, handle_var_decl): Adjust. * src/abg-symtab-reader.cc (symtab::{lookup_undefined_function_symbol, lookup_undefined_variable_symbol, function_symbol_is_undefined, variable_symbol_is_undefined, collect_undefined_fns_and_vars_linkage_names}): Define new member functions. (symtab::symtab): Initialize the new cached_undefined_symbol_names_ data member. * src/abg-symtab-reader.h (symtab::{lookup_undefined_function_symbol, lookup_undefined_variable_symbol, function_symbol_is_undefined, variable_symbol_is_undefined, collect_undefined_fns_and_vars_linkage_names}): Declare new member functions. (symtab::{undefined_variable_linkage_names_, cached_undefined_symbol_names_}): Define new data members. (symtab::load_): Consider undefined symbol of type STT_NOTYPE as being undefined global variables. It's what I am seeing in ELF binaries. * src/abg-symtab-reader.h (symtab::{lookup_undefined_function_symbol, lookup_undefined_variable_symbol, function_symbol_is_undefined, variable_symbol_is_undefined}): Declare new member functions. (symtab::{undefined_function_linkage_names_, undefined_variable_linkage_names_}): Define new member variables. * src/abg-writer.cc (write_var_decl, write_function_decl): Emit a reference to a symbol only when the symbol is defined. * tools/abicompat.cc (report_function_changes) (report_variable_changes) (compare_expected_against_provided_functions) (compare_expected_against_provided_variables): Define new static functions. (perform_compat_check_in_weak_mode): Use the new static functions above. Compare interfaces expected by the application corpus against interfaces provided by the library. Report the changes. Do that in the reverse direction as well. (read_corpus): Instruct the corpus reader to load the set of undefined interfaces too. * tests/data/test-abicompat/test6-var-changed-app: Remove file. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/test-abicompat/libtest6-undefined-var.so: Add new binary input file. * tests/data/test-abicompat/test6-undefined-var.cc: Add sourcefile for the binary input file above. * tests/data/test-abicompat/test6-var-changed-report-2.txt: New reference output file. * tests/data/Makefile.am: Update the list of distributed files accordingly. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v0.so: Adjust. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v1.so: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v0.so: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v1.so: Likewise. * tests/data/test-abicompat/libtest7-fn-changed-libapp-v0.so: Likewise. * tests/data/test-abicompat/libtest7-fn-changed-libapp-v1.so: Likewise. * tests/data/test-abicompat/libtest8-fn-changed-libapp-v0.so: Likewise. * tests/data/test-abicompat/libtest8-fn-changed-libapp-v1.so: Likewise. * tests/data/test-abicompat/libtest9-fn-changed-v0.so: Likewise. * tests/data/test-abicompat/libtest9-fn-changed-v1.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v0.cc: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v1.cc: Likewise. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test6-var-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test7-fn-changed-app: Likewise. * tests/data/test-abicompat/test7-fn-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test7-fn-changed-report-2.txt: Likewise. * tests/data/test-abicompat/test8-fn-changed-app: Likewise. * tests/data/test-abicompat/test8-fn-changed-libapp-v1.c: Likewise. * tests/data/test-abicompat/test9-fn-changed-app: Likewise. * tests/data/test-abicompat/test9-fn-changed-app.cc: Likewise. * tests/data/test-annotate/libtest23.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test1.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.ab: Likewise.i * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test2.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-annotate/test8-qualified-this-pointer.so.abi: Likewise. * tests/data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64--dbus-glib-0.104-3.fc23.armv7hl-report-0.txt: Likewise. * tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt: Likewise. * tests/data/test-fedabipkgdiff/test0-from-fc20-to-fc23-dbus-glib-report-0.txt: Likewise. * tests/data/test-fedabipkgdiff/test2-dbus-glib-0.100.2-2.fc20--dbus-glib-0.106-1.fc23-report-0.txt: Likewise. * tests/data/test-fedabipkgdiff/test3-dbus-glib-0.100.2-2.fc20.i686--dbus-glib-0.106-1.fc23.i686-report-0.txt: Likewise. * tests/data/test-fedabipkgdiff/vte291-0.39.1-1.fc22.x86_64--vte291-0.39.90-1.fc22.x86_64-report-0.txt: Likewise. * tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Likewise. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise. * tests/data/test-read-dwarf/PR26261/PR26261-exe.abi: Likewise. * tests/data/test-read-dwarf/libtest23.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test-libaaudio.so.abi: Likewise. * tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise. * tests/data/test-read-dwarf/test1.abi: Likewise. * tests/data/test-read-dwarf/test1.hash.abi: 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/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test2.so.abi: Likewise. * tests/data/test-read-dwarf/test2.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: Likewise. * tests/data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. * tests/test-abicompat.cc (in_out_specs): Adjust. * tests/test-read-ctf.cc (test_task_ctf::perform): Do not load undefined interfaces, by default. * tests/test-symtab.cc (Symtab::SimpleSymtabs) (Symtab::SymtabWithWhitelist, Symtab::AliasedFunctionSymbols): Adjust the expected undefined variable symbols counts. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
534 lines
13 KiB
C++
534 lines
13 KiB
C++
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
// -*- Mode: C++ -*-
|
|
//
|
|
// Copyright (C) 2021-2023 Oracle, Inc.
|
|
//
|
|
// Author: Guillermo E. Martinez
|
|
|
|
/// @file
|
|
///
|
|
/// This file implement the CTF testsuite. It reads ELF binaries
|
|
/// containing CTF, save them in XML corpus files and diff the
|
|
/// corpus files against reference XML corpus files.
|
|
|
|
#include <cstdlib>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
#include "abg-ctf-reader.h"
|
|
#include "test-read-common.h"
|
|
|
|
using std::string;
|
|
using std::cerr;
|
|
using std::vector;
|
|
|
|
using abigail::tests::read_common::InOutSpec;
|
|
using abigail::tests::read_common::test_task;
|
|
using abigail::tests::read_common::display_usage;
|
|
using abigail::tests::read_common::options;
|
|
|
|
using abigail::xml_writer::SEQUENCE_TYPE_ID_STYLE;
|
|
using abigail::xml_writer::HASH_TYPE_ID_STYLE;
|
|
using abigail::tools_utils::emit_prefix;
|
|
|
|
using namespace abigail;
|
|
|
|
static InOutSpec in_out_specs[] =
|
|
{
|
|
{
|
|
"data/test-read-ctf/test0",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test0.abi",
|
|
"output/test-read-ctf/test0.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test0",
|
|
"",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test0.hash.abi",
|
|
"output/test-read-ctf/test0.hash.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test1.so",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test1.so.abi",
|
|
"output/test-read-ctf/test1.so.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test1.so",
|
|
"",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test1.so.hash.abi",
|
|
"output/test-read-ctf/test1.so.hash.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test2.so",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test2.so.abi",
|
|
"output/test-read-ctf/test2.so.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test2.so",
|
|
"",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test2.so.hash.abi",
|
|
"output/test-read-ctf/test2.so.hash.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-common/test3.so",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test3.so.abi",
|
|
"output/test-read-ctf/test3.so.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-common/test3.so",
|
|
"",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test3.so.hash.abi",
|
|
"output/test-read-ctf/test3.so.hash.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-enum-many.o",
|
|
"",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-enum-many.o.hash.abi",
|
|
"output/test-read-ctf/test-enum-many.o.hash.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-ambiguous-struct-A.o",
|
|
"",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi",
|
|
"output/test-read-ctf/test-ambiguous-struct-A.o.hash.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-ambiguous-struct-B.o",
|
|
"",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi",
|
|
"output/test-read-ctf/test-ambiguous-struct-B.o.hash.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-conflicting-type-syms-a.o",
|
|
"",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi",
|
|
"output/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-conflicting-type-syms-b.o",
|
|
"",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi",
|
|
"output/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-common/test4.so",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test4.so.abi",
|
|
"output/test-read-ctf/test4.so.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-common/test4.so",
|
|
"",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test4.so.hash.abi",
|
|
"output/test-read-ctf/test4.so.hash.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test5.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test5.o.abi",
|
|
"output/test-read-ctf/test5.o.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test7.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test7.o.abi",
|
|
"output/test-read-ctf/test7.o.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test8.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test8.o.abi",
|
|
"output/test-read-ctf/test8.o.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test9.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test9.o.abi",
|
|
"output/test-read-ctf/test9.o.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-enum.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-enum.o.abi",
|
|
"output/test-read-ctf/test-enum.o.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-enum-symbol.o",
|
|
"",
|
|
"",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-enum-symbol.o.hash.abi",
|
|
"output/test-read-ctf/test-enum-symbol.o.hash.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-dynamic-array.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-dynamic-array.o.abi",
|
|
"output/test-read-ctf/test-dynamic-array.o.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-anonymous-fields.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-anonymous-fields.o.abi",
|
|
"output/test-read-ctf/test-anonymous-fields.o.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-common/PR27700/test-PR27700.o",
|
|
"",
|
|
"data/test-read-common/PR27700/pub-incdir",
|
|
HASH_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/PR27700/test-PR27700.abi",
|
|
"output/test-read-ctf/PR27700/test-PR27700.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-callback.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-callback.abi",
|
|
"output/test-read-ctf/test-callback.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-array-of-pointers.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-array-of-pointers.abi",
|
|
"output/test-read-ctf/test-array-of-pointers.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-functions-declaration.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-functions-declaration.abi",
|
|
"output/test-read-ctf/test-functions-declaration.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-forward-type-decl.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-forward-type-decl.abi",
|
|
"output/test-read-ctf/test-forward-type-decl.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-list-struct.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-list-struct.abi",
|
|
"output/test-read-ctf/test-list-struct.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-common/test-PR26568-1.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-PR26568-1.o.abi",
|
|
"output/test-read-ctf/test-PR26568-1.o.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-common/test-PR26568-2.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-PR26568-2.o.abi",
|
|
"output/test-read-ctf/test-PR26568-2.o.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-callback2.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-callback2.abi",
|
|
"output/test-read-ctf/test-callback2.abi",
|
|
"--ctf"
|
|
},
|
|
// out-of-tree kernel module.
|
|
{
|
|
"data/test-read-ctf/test-linux-module.ko",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-linux-module.abi",
|
|
"output/test-read-ctf/test-linux-module.abi",
|
|
"--ctf"
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-alias.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-alias.o.abi",
|
|
"output/test-read-ctf/test-alias.o.abi",
|
|
"--ctf"
|
|
},
|
|
// CTF fallback feature.
|
|
{
|
|
"data/test-read-ctf/test-fallback.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-fallback.abi",
|
|
"output/test-read-ctf/test-fallback.abi",
|
|
NULL,
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-bitfield.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-bitfield.abi",
|
|
"output/test-read-ctf/test-bitfield.abi",
|
|
"--ctf",
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-bitfield-enum.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-bitfield-enum.abi",
|
|
"output/test-read-ctf/test-bitfield-enum.abi",
|
|
"--ctf",
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-const-array.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-const-array.abi",
|
|
"output/test-read-ctf/test-const-array.abi",
|
|
"--ctf",
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-array-mdimension.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-array-mdimension.abi",
|
|
"output/test-read-ctf/test-array-mdimension.abi",
|
|
"--ctf",
|
|
},
|
|
{
|
|
"data/test-read-ctf/test-array-size.o",
|
|
"",
|
|
"",
|
|
SEQUENCE_TYPE_ID_STYLE,
|
|
"data/test-read-ctf/test-array-size.abi",
|
|
"output/test-read-ctf/test-array-size.abi",
|
|
"--ctf",
|
|
},
|
|
// This should be the last entry.
|
|
{NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL, NULL}
|
|
};
|
|
|
|
/// Task specialization to perform CTF tests.
|
|
struct test_task_ctf : public test_task
|
|
{
|
|
test_task_ctf(const InOutSpec &s,
|
|
string& a_out_abi_base,
|
|
string& a_in_elf_base,
|
|
string& a_in_abi_base);
|
|
virtual void
|
|
perform();
|
|
|
|
virtual
|
|
~test_task_ctf()
|
|
{}
|
|
}; // end struct test_task_ctf
|
|
|
|
/// Constructor.
|
|
///
|
|
/// Task to be executed for each CTF test entry in @ref
|
|
/// abigail::tests::read_common::InOutSpec.
|
|
/// @param InOutSpec the array containing set of tests.
|
|
///
|
|
/// @param a_out_abi_base the output base directory for abixml files.
|
|
///
|
|
/// @param a_in_elf_base the input base directory for object files.
|
|
///
|
|
/// @param a_in_elf_base the input base directory for expected
|
|
/// abixml files.
|
|
test_task_ctf::test_task_ctf(const InOutSpec &s,
|
|
string& a_out_abi_base,
|
|
string& a_in_elf_base,
|
|
string& a_in_abi_base)
|
|
: test_task(s, a_out_abi_base, a_in_elf_base, a_in_abi_base)
|
|
{}
|
|
|
|
/// The thread function to execute each CTF test entry in @ref
|
|
/// abigail::tests::read_common::InOutSpec.
|
|
///
|
|
/// This reads the corpus into memory, saves it to disk, loads it
|
|
/// again and compares the new in-memory representation against the
|
|
void
|
|
test_task_ctf::perform()
|
|
{
|
|
abigail::ir::environment env;
|
|
|
|
set_in_elf_path();
|
|
set_in_suppr_spec_path();
|
|
|
|
abigail::fe_iface::status status =
|
|
abigail::fe_iface::STATUS_UNKNOWN;
|
|
vector<char**> di_roots;
|
|
ABG_ASSERT(abigail::tools_utils::file_exists(in_elf_path));
|
|
|
|
abigail::elf_based_reader_sptr rdr = ctf::create_reader(in_elf_path,
|
|
di_roots, env);
|
|
ABG_ASSERT(rdr);
|
|
rdr->options().load_undefined_interfaces = false;
|
|
corpus_sptr corp = rdr->read_corpus(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("");
|
|
|
|
if (!(is_ok = set_out_abi_path()))
|
|
return;
|
|
|
|
if (!(is_ok = serialize_corpus(out_abi_path, corp)))
|
|
return;
|
|
|
|
if (!(is_ok = run_abidw()))
|
|
return;
|
|
|
|
if (!(is_ok = run_diff()))
|
|
return;
|
|
}
|
|
|
|
/// Create a new CTF instance for task to be execute by the testsuite.
|
|
///
|
|
/// @param s the @ref abigail::tests::read_common::InOutSpec
|
|
/// tests container.
|
|
///
|
|
/// @param a_out_abi_base the output base directory for abixml files.
|
|
///
|
|
/// @param a_in_elf_base the input base directory for object files.
|
|
///
|
|
/// @param a_in_abi_base the input base directory for abixml files.
|
|
///
|
|
/// @return abigail::tests::read_common::test_task instance.
|
|
static test_task*
|
|
new_task(const InOutSpec* s, string& a_out_abi_base,
|
|
string& a_in_elf_base, string& a_in_abi_base)
|
|
{
|
|
return new test_task_ctf(*s, a_out_abi_base,
|
|
a_in_elf_base, a_in_abi_base);
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
options opts;
|
|
if (!parse_command_line(argc, argv, opts))
|
|
{
|
|
if (!opts.wrong_option.empty())
|
|
emit_prefix(argv[0], cerr)
|
|
<< "unrecognized option: " << opts.wrong_option << "\n";
|
|
display_usage(argv[0], cerr);
|
|
return 1;
|
|
}
|
|
|
|
// compute number of tests to be executed.
|
|
const size_t num_tests = sizeof(in_out_specs) / sizeof(InOutSpec) - 1;
|
|
|
|
return run_tests(num_tests, in_out_specs, opts, new_task);
|
|
}
|