mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-24 02:32:16 +00:00
41d0ad035f
While working on something else, I noticed that the code for handling copying symbols (and their aliases) was broken, and so comparing two symbols which main name were different by which had aliases that were equal was wrongly resulting in the two symbol being different. I think we shouldn't actually copy symbols and their aliases. Once a symbol is allocated, interested code should just manipulate that symbol by address rather than by value an thus do away with the copying. The patch does that, essentially. In the implementation of a symbol, the aliases as well as the main symbol are now weak pointers, rather than naked pointers. Numerous API entry points that were taking containers of elf_symbol (and were copying elf_symbols over) are not taking containers of smart pointers to elf_symbol. Copying of instances of elf_symbol is now thus disabled. As a result many tests that were exercising elf_symbols (with alias) comparison have been updated. As a result, many empty sub-result of PR libabigail/PR17948 are now fixed. * include/abg-ir.h (elf_symbol_wptr): New typedef. (elf_symbol): Make the constructors and assignment operator private. The type can neither be copied nor created with the new operator. (elf_symbol::create): New static member function. (elf_symbol::{get_main_symbol, get_next_alias, add_alias}): Adjust. ( compute_aliases_for_elf_symbol): Likewise. (elf_symbol::operator=): Make this private. (elf_symbol::get_alias_which_equals): Declare new member function. * src/abg-comp-filter.cc (function_name_changed_but_not_symbol): Adjust. * src/abg-comparison.cc (class_diff::ensure_lookup_tables_populated): Adjust. * src/abg-corpus.cc (corpus::priv::build_unreferenced_symbols_tables): Likewise. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Adjust. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab, lookup_symbol_from_elf_hash_tab) (lookup_symbol_from_symtab, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf): Adjust. (read_context::lookup_elf_symbol_from_index): Likewise. (read_context::lookup_elf_fn_symbol_from_address): Likewise. (read_context::lookup_elf_var_symbol_from_address): Likewise. (read_context::lookup_public_function_symbol_from_elf): Likewise. (read_context::lookup_public_variable_symbol_from_elf): Likewise. (read_context::load_symbol_maps): Likewise. (build_var_decl, build_function_decl): Likewise. * src/abg-ir.cc (elf_symbol::priv::{main_symbol_, next_alias_}): Change the type of these from elf_symbol* to elf_symbol_wptr. (elf_symbol::priv::priv): Adjust. (elf_symbol::{create, get_alias_which_equals}): Define new functions. (textually_equals): Likewise. (elf_symbol::{get_main_symbol, is_main_symbol, get_next_alias, add_alias}): Adjust to return or take elf_symbol_sptr type, rather than a elf_symbol* one. (elf_symbol::{get_aliases_id_string, does_alias}): Adjust. (compute_alias_for_elf_symbol): Likewise. (elf_symbol::operator==): Two symbols A and B are now equal if A has at least one alias that is textually equal to B. (equals): In the overload for function_decls, in the part where we compare the decl_base part of the functions without considering their decl names, we now also omit considering their linkage names, because we compared they symbols before. * tools/abisym.cc (main): Adjust. * tests/data/test-diff-dwarf/test12-report.txt: Adjust. * tests/data/test-diff-dwarf/test12-report.txt: Adjust. * tests/data/test-diff-dwarf/test18-alias-sym-report-0.txt: Adjust. * tests/data/test-diff-dwarf/test8-report.txt: Adjust. * tests/data/test-diff-filter/test10-report.txt: Adjust. * tests/data/test-diff-filter/test13-report.txt: Adjust. * tests/data/test-diff-filter/test2-report.txt: Adjust. * tests/data/test-diff-filter/test20-inline-report-0.txt: Adjust. * tests/data/test-diff-filter/test20-inline-report-1.txt: Adjust. * tests/data/test-diff-filter/test9-report.txt: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
165 lines
3.9 KiB
C++
165 lines
3.9 KiB
C++
// -*- Mode: C++ -*-
|
|
//
|
|
// Copyright (C) 2013-2015 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
|
|
///
|
|
/// This program takes parameters to open an elf file, lookup a symbol
|
|
/// in its symbol tables and report what it sees.
|
|
|
|
#include <elf.h>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include "abg-dwarf-reader.h"
|
|
#include "abg-ir.h"
|
|
|
|
using std::cout;
|
|
using std::cerr;
|
|
using std::string;
|
|
using std::ostream;
|
|
using std::ostringstream;
|
|
using std::vector;
|
|
|
|
using abigail::dwarf_reader::lookup_symbol_from_elf;
|
|
using abigail::elf_symbol;
|
|
using abigail::elf_symbol_sptr;
|
|
|
|
struct options
|
|
{
|
|
bool show_help;
|
|
char* elf_path;
|
|
char* symbol_name;
|
|
bool demangle;
|
|
bool absolute_path;
|
|
|
|
options()
|
|
: show_help(false),
|
|
elf_path(0),
|
|
symbol_name(0),
|
|
demangle(false),
|
|
absolute_path(true)
|
|
{}
|
|
};
|
|
|
|
static void
|
|
display_usage(const string& prog_name, ostream &out)
|
|
{
|
|
out << "usage: " << prog_name << " [options] <elf file> <symbol-name>\n"
|
|
<< "where [options] can be:\n"
|
|
<< " --help display this help string\n"
|
|
<< " --demangle demangle the symbols from the symbol table\n"
|
|
<< " --no-absolute-path do not show absolute paths in messages\n";
|
|
}
|
|
|
|
static void
|
|
parse_command_line(int argc, char* argv[], options& opts)
|
|
{
|
|
if (argc < 2)
|
|
{
|
|
opts.show_help = true;
|
|
return;
|
|
}
|
|
|
|
for (int i = 1; i < argc; ++i)
|
|
{
|
|
if (argv[i][0] != '-')
|
|
{
|
|
if (!opts.elf_path)
|
|
opts.elf_path = argv[i];
|
|
else if (!opts.symbol_name)
|
|
opts.symbol_name = argv[i] ;
|
|
else
|
|
{
|
|
opts.show_help = true;
|
|
return;
|
|
}
|
|
}
|
|
else if (!strcmp(argv[i], "--help")
|
|
|| !strcmp(argv[i], "-h"))
|
|
{
|
|
opts.show_help = true;
|
|
return;
|
|
}
|
|
else if (!strcmp(argv[i], "--demangle"))
|
|
opts.demangle = true;
|
|
else if (!strcmp(argv[i], "--no-absolute-path"))
|
|
opts.absolute_path = false;
|
|
else
|
|
opts.show_help = true;
|
|
}
|
|
}
|
|
|
|
int
|
|
main(int argc, char* argv[])
|
|
{
|
|
options opts;
|
|
parse_command_line(argc, argv, opts);
|
|
|
|
if (opts.show_help)
|
|
{
|
|
display_usage(argv[0], cout);
|
|
return 1;
|
|
}
|
|
assert(opts.elf_path != 0
|
|
&& opts.symbol_name != 0);
|
|
|
|
string p = opts.elf_path, n = opts.symbol_name;
|
|
vector<elf_symbol_sptr> syms;
|
|
if (!lookup_symbol_from_elf(p, n, opts.demangle, syms))
|
|
{
|
|
cout << "could not find symbol '"
|
|
<< opts.symbol_name
|
|
<< "' in file '";
|
|
if (opts.absolute_path)
|
|
cout << opts.elf_path << "'\n";
|
|
else
|
|
cout << basename(opts.elf_path);
|
|
return 0;
|
|
}
|
|
|
|
elf_symbol_sptr sym = syms[0];
|
|
cout << " found symbol '" << n << "'";
|
|
if (n != sym->get_name())
|
|
cout << " (" << sym->get_name() << ")";
|
|
cout << ", an instance of "
|
|
<< (elf_symbol::type) sym->get_type()
|
|
<< " of " << sym->get_binding();
|
|
if (syms.size() > 1 || !sym->get_version().is_empty())
|
|
{
|
|
cout << ", of version";
|
|
if (syms.size () > 1)
|
|
cout << "s";
|
|
cout << " ";
|
|
for (vector<elf_symbol_sptr>::const_iterator i = syms.begin();
|
|
i != syms.end();
|
|
++i)
|
|
{
|
|
if (i != syms.begin())
|
|
cout << ", ";
|
|
cout << "'" << (*i)->get_version().str() << "'";
|
|
}
|
|
}
|
|
cout << '\n';
|
|
|
|
return 0;
|
|
}
|