mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-24 02:32:16 +00:00
c495a5c5f0
Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
335 lines
7.3 KiB
C++
335 lines
7.3 KiB
C++
// -*- mode: C++ -*-
|
|
//
|
|
// Copyright (C) 2013-2016 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/>.
|
|
|
|
/// @file
|
|
|
|
#ifndef __ABG_CORPUS_H__
|
|
#define __ABG_CORPUS_H__
|
|
|
|
#include <abg-ir.h>
|
|
|
|
namespace abigail
|
|
{
|
|
|
|
namespace ir
|
|
{
|
|
|
|
class corpus;
|
|
/// A convenience typedef for shared pointer to @ref corpus.
|
|
typedef shared_ptr<corpus> corpus_sptr;
|
|
|
|
/// This is the abstraction of a set of translation units (themselves
|
|
/// seen as bundles of unitary abi artefacts like types and decls)
|
|
/// bundled together as a corpus. A corpus is thus the Application
|
|
/// binary interface of a program, a library or just a set of modules
|
|
/// put together.
|
|
class corpus
|
|
{
|
|
public:
|
|
struct priv;
|
|
/// Convenience typedef for shared_ptr of corpus::priv
|
|
typedef shared_ptr<priv> priv_sptr;
|
|
|
|
/// A convenience typedef for std::vector<string>.
|
|
typedef vector<string> strings_type;
|
|
|
|
/// Convenience typedef for std::vector<abigail::ir::function_decl*>
|
|
typedef vector<function_decl*> functions;
|
|
|
|
///Convenience typedef for std::vector<abigail::ir::var_decl*>
|
|
typedef vector<var_decl*> variables;
|
|
|
|
class exported_decls_builder;
|
|
|
|
/// Convenience typedef for shared_ptr<exported_decls_builder>.
|
|
typedef shared_ptr<exported_decls_builder> exported_decls_builder_sptr;
|
|
|
|
/// This abstracts where the corpus comes from. That is, either it
|
|
/// has been read from the native xml format, from DWARF or built
|
|
/// artificially using the library's API.
|
|
enum origin
|
|
{
|
|
ARTIFICIAL_ORIGIN = 0,
|
|
NATIVE_XML_ORIGIN,
|
|
DWARF_ORIGIN
|
|
};
|
|
|
|
private:
|
|
corpus();
|
|
|
|
void record_canonical_type(const type_base_sptr&) const;
|
|
type_base_sptr lookup_canonical_type(const string& qualified_name) const;
|
|
|
|
public:
|
|
shared_ptr<priv> priv_;
|
|
|
|
corpus(ir::environment*, const string& path= "");
|
|
|
|
const environment*
|
|
get_environment() const;
|
|
|
|
environment*
|
|
get_environment();
|
|
|
|
void
|
|
set_environment(environment*) const;
|
|
|
|
void
|
|
add(const translation_unit_sptr);
|
|
|
|
const translation_units&
|
|
get_translation_units() const;
|
|
|
|
void
|
|
drop_translation_units();
|
|
|
|
type_maps&
|
|
get_types();
|
|
|
|
const type_maps&
|
|
get_types() const;
|
|
|
|
origin
|
|
get_origin() const;
|
|
|
|
void
|
|
set_origin(origin);
|
|
|
|
string&
|
|
get_path() const;
|
|
|
|
void
|
|
set_path(const string&);
|
|
|
|
const vector<string>&
|
|
get_needed() const;
|
|
|
|
void
|
|
set_needed(const vector<string>&);
|
|
|
|
const string&
|
|
get_soname();
|
|
|
|
void
|
|
set_soname(const string&);
|
|
|
|
const string&
|
|
get_architecture_name();
|
|
|
|
void
|
|
set_architecture_name(const string&);
|
|
|
|
bool
|
|
is_empty() const;
|
|
|
|
bool
|
|
operator==(const corpus&) const;
|
|
|
|
void
|
|
set_fun_symbol_map(string_elf_symbols_map_sptr);
|
|
|
|
void
|
|
set_undefined_fun_symbol_map(string_elf_symbols_map_sptr);
|
|
|
|
void
|
|
set_var_symbol_map(string_elf_symbols_map_sptr);
|
|
|
|
void
|
|
set_undefined_var_symbol_map(string_elf_symbols_map_sptr);
|
|
|
|
const string_elf_symbols_map_sptr
|
|
get_fun_symbol_map_sptr() const;
|
|
|
|
const string_elf_symbols_map_type&
|
|
get_fun_symbol_map() const;
|
|
|
|
const string_elf_symbols_map_sptr
|
|
get_undefined_fun_symbol_map_sptr() const;
|
|
|
|
const string_elf_symbols_map_type&
|
|
get_undefined_fun_symbol_map() const;
|
|
|
|
const elf_symbols&
|
|
get_sorted_fun_symbols() const;
|
|
|
|
const elf_symbols&
|
|
get_sorted_undefined_fun_symbols() const;
|
|
|
|
const string_elf_symbols_map_sptr
|
|
get_var_symbol_map_sptr() const;
|
|
|
|
const string_elf_symbols_map_type&
|
|
get_var_symbol_map() const;
|
|
|
|
const string_elf_symbols_map_sptr
|
|
get_undefined_var_symbol_map_sptr() const;
|
|
|
|
const string_elf_symbols_map_type&
|
|
get_undefined_var_symbol_map() const;
|
|
|
|
const elf_symbols&
|
|
get_sorted_var_symbols() const;
|
|
|
|
const elf_symbols&
|
|
get_sorted_undefined_var_symbols() const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_function_symbol(const string& n) const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_function_symbol(const string& symbol_name,
|
|
const elf_symbol::version& version) const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_function_symbol(const elf_symbol& symbol) const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_variable_symbol(const string& n) const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_variable_symbol(const string& symbol_name,
|
|
const elf_symbol::version& version) const;
|
|
|
|
const elf_symbol_sptr
|
|
lookup_variable_symbol(const elf_symbol& symbol) const;
|
|
|
|
const functions&
|
|
get_functions() const;
|
|
|
|
const vector<function_decl*>*
|
|
lookup_functions(const string& id) const;
|
|
|
|
void
|
|
sort_functions();
|
|
|
|
const variables&
|
|
get_variables() const;
|
|
|
|
void
|
|
sort_variables();
|
|
|
|
const elf_symbols&
|
|
get_unreferenced_function_symbols() const;
|
|
|
|
const elf_symbols&
|
|
get_unreferenced_variable_symbols() const;
|
|
|
|
vector<string>&
|
|
get_regex_patterns_of_fns_to_suppress();
|
|
|
|
const vector<string>&
|
|
get_regex_patterns_of_fns_to_suppress() const;
|
|
|
|
vector<string>&
|
|
get_regex_patterns_of_vars_to_suppress();
|
|
|
|
const vector<string>&
|
|
get_regex_patterns_of_vars_to_suppress() const;
|
|
|
|
vector<string>&
|
|
get_regex_patterns_of_fns_to_keep();
|
|
|
|
const vector<string>&
|
|
get_regex_patterns_of_fns_to_keep() const;
|
|
|
|
vector<string>&
|
|
get_sym_ids_of_fns_to_keep();
|
|
|
|
const vector<string>&
|
|
get_sym_ids_of_fns_to_keep() const;
|
|
|
|
vector<string>&
|
|
get_regex_patterns_of_vars_to_keep();
|
|
|
|
const vector<string>&
|
|
get_regex_patterns_of_vars_to_keep() const;
|
|
|
|
vector<string>&
|
|
get_sym_ids_of_vars_to_keep();
|
|
|
|
const vector<string>&
|
|
get_sym_ids_of_vars_to_keep() const;
|
|
|
|
void
|
|
maybe_drop_some_exported_decls();
|
|
|
|
exported_decls_builder_sptr
|
|
get_exported_decls_builder() const;
|
|
|
|
friend class type_base;
|
|
};// end class corpus.
|
|
|
|
/// Abstracts the building of the set of exported variables and
|
|
/// functions.
|
|
///
|
|
/// Given a function or variable, this type can decide if it belongs
|
|
/// to the list of exported functions and variables based on all the
|
|
/// parameters needed.
|
|
class corpus::exported_decls_builder
|
|
{
|
|
public:
|
|
class priv;
|
|
|
|
/// Convenience typedef for shared_ptr<priv>
|
|
typedef shared_ptr<priv> priv_sptr;
|
|
|
|
friend class corpus;
|
|
|
|
private:
|
|
priv_sptr priv_;
|
|
|
|
// Forbid default construction.
|
|
exported_decls_builder();
|
|
|
|
public:
|
|
|
|
exported_decls_builder(functions& fns,
|
|
variables& vars,
|
|
strings_type& fns_suppress_regexps,
|
|
strings_type& vars_suppress_regexps,
|
|
strings_type& fns_keep_regexps,
|
|
strings_type& vars_keep_regexps,
|
|
strings_type& sym_id_of_fns_to_keep,
|
|
strings_type& sym_id_of_vars_to_keep);
|
|
|
|
|
|
const functions&
|
|
exported_functions() const;
|
|
|
|
functions&
|
|
exported_functions();
|
|
|
|
const variables&
|
|
exported_variables() const;
|
|
|
|
variables&
|
|
exported_variables();
|
|
|
|
void
|
|
maybe_add_fn_to_exported_fns(function_decl*);
|
|
|
|
void
|
|
maybe_add_var_to_exported_vars(var_decl*);
|
|
}; //corpus::exported_decls_builder
|
|
|
|
}// end namespace ir
|
|
}//end namespace abigail
|
|
#endif //__ABG_CORPUS_H__
|