2014-04-21 15:43:15 +00:00
|
|
|
// -*- Mode: C++ -*-
|
|
|
|
//
|
2020-02-21 15:42:35 +00:00
|
|
|
// Copyright (C) 2013-2020 Red Hat, Inc.
|
2014-04-21 15:43:15 +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
|
|
|
|
///
|
|
|
|
/// This program tests the ELF symbols lookup APIs from
|
|
|
|
/// abigail::dwarf_reader. It uses the lookupsym tool from the
|
|
|
|
/// libabigail distribution.
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include "abg-tools-utils.h"
|
|
|
|
#include "test-utils.h"
|
|
|
|
|
|
|
|
using std::cerr;
|
|
|
|
using std::string;
|
|
|
|
|
|
|
|
struct InOutSpec
|
|
|
|
{
|
|
|
|
const char* in_elf_path;
|
|
|
|
const char* symbol;
|
2014-09-26 08:58:16 +00:00
|
|
|
const char* abisym_options;
|
2014-04-21 15:43:15 +00:00
|
|
|
const char* in_report_path;
|
|
|
|
const char* out_report_path;
|
|
|
|
}; // end struct InOutSpec
|
|
|
|
|
|
|
|
InOutSpec in_out_specs[] =
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"data/test-lookup-syms/test0.o",
|
|
|
|
"main",
|
|
|
|
"",
|
|
|
|
"data/test-lookup-syms/test0-report.txt",
|
|
|
|
"output/test-lookup-syms/test0-report.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-lookup-syms/test0.o",
|
|
|
|
"foo",
|
|
|
|
"",
|
|
|
|
"data/test-lookup-syms/test01-report.txt",
|
|
|
|
"output/test-lookup-syms/test01-report.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-lookup-syms/test0.o",
|
|
|
|
"\"bar(char)\"",
|
|
|
|
"--demangle",
|
|
|
|
"data/test-lookup-syms/test02-report.txt",
|
|
|
|
"output/test-lookup-syms/test02-report.txt"
|
|
|
|
},
|
Initial support for elf symbol (versionning) during decl comparison
* include/abg-fwd.h (get_linkage_name): Remove.
* include/abg-dwarf-reader.h (enum symbol_type)
(enum symbol_binding): Move these into abg-ir.h.
(lookup_symbol_from_elf, lookup_public_function_symbol_from_elf):
Adjust.
* src/abg-dwarf-reader.cc (eval_last_constant_dwarf_sub_expr):
Declare this before using it.
(die_address_attribute, die_location_address)
(stt_to_elf_symbol_type, stb_to_elf_symbol_binding)
(find_hash_table_section_index, find_symbol_table_section)
(find_symbol_table_section_index, find_text_section)
(find_bss_section, compare_symbol_name)
(get_symbol_versionning_sections get_version_for_symbol)
(lookup_symbol_from_sysv_hash_tab)
(lookup_symbol_from_gnu_hash_tab, get_elf_class_size_in_bytes)
(bloom_word_at, setup_gnu_ht, lookup_symbol_from_elf_hash_tab)
(lookup_symbol_from_symtab, maybe_adjust_fn_sym_address)
(maybe_adjust_var_sym_address): New static functions.
(enum hash_table_kind): New enum.
(struct gnu_ht): New struct.
(read_context::var_decls_to_add_): Renamed var_decls_to_add into
this.
(read_context::{fun, var}_sym_addr_sym_index_map_): New member.
(read_context::{lookup_symbol_from_elf,
lookup_elf_symbol_from_index, lookup_elf_fn_symbol_from_address,
lookup_elf_var_symbol_from_address, fun_sym_addr_sym_index_map,
var_sym_addr_sym_index_map, load_symbol_addr_to_index_maps,
get_function_address, get_variable_address}): New member
functions.
(read_context::lookup_public_{variable,
function}_symbol_from_elf): Adjust.
(op_pushes_constant_value): Fix a bug here.
(lookup_symbol_from_elf): Adjust. Support cases where there is no
elf hash table, e.g, for relocatable files.
(lookup_public_function_symbol_from_elf)
(lookup_public_variable_symbol_from_elf): Adjust.
(build_var_decl): Allow updating the var_decl to associate it with
its underlying symbol. In that case, if the linkage name is not
set, set it to the symbol name.
(build_function_decl): Likewise for function_decl.
(operator<<(std::ostream&, symbol_type)):
(operator<<(std::ostream&, symbol_binding)): Move these do
abg-ir.cc.
* include/abg-ir.h (class elf_symbol): Declare new class. Move
enum symbol_binding and enum symbol_type (from abg-dwarf-reader.h) to
elf_symbol::binding and elf_symbol::type here.
(operator<<(std::ostream&, elf_symbol::type))
(operator<<(std::ostream&, elf_symbol::binding))
(operator==(const elf_symbol_sptr, const elf_symbol_sptr)): New
operators.
(class elf_symbol::version): Declare new class.
(class var_decl): Make this pimpl, and add ...
(var_decl::{g,s}et_symbol): ... new member functions.
(class function_decl): Likewise, make this pimpl and add ...
(function_decl::{g,s}et_symbol): ... new member functions.
* src/abg-ir.cc (struct elf_symbol, elf_symbol::priv): New
types.
(elf_symbol::*): Lots of new members and member functions.
(operator==(const elf_symbol_sptr, const elf_symbol_sptr)): New.
(operator<<(std::ostream&, elf_symbol::type)): New.
(operator<<(std::ostream&, elf_symbol::binding)): New.
(elf_symbol::version::priv): New type.
(elf_symbol::version::*): Lots of member functions.
(get_linkage_name): Removed.
(var_decl::priv): New type. Pimplify the thing.
(var_decl::{s,g}et_symbol): New.
(var_decl::operator==): Take symbols in account in the comparison.
(function_decl::priv): New type.
(function_decl::*): Pimplify.
(function_decl::{s,g}et_symbol): New.
(function_decl::operator==): Take symbols in account in the
comparison.
* include/abg-comparison.h (diff_context::show_linkage_name): New
member function.
* src/abg-comparison.cc (diff_context::priv::show_linkage_name_):
New member.
(diff_context::priv::priv): Initialize it.
(diff_context::show_linkage_names): New member function.
(corpus_diff::report): If the user used --show-linkage-names,
display the linkage name after the name of the functions. Add
missing "'" in the some spots.
* tools/bidiff.cc (options.show_linkage_names): New member.
(display_usage, parse_command_line): Support --linkage-names.
* tools/bisym.cc (show_help): Add '\n' at the end of help string
for --demangle. Add --no-absolute-path option.
(parse_command_line): Support --no-absolute-path.
(main): Adjust for symbol (versionning) support. Consider that
the program successfully completed even when the symbol wasn't
found. Support --no-absolute-path.
* tests/data/test-lookup-syms/test0-report.txt: New.
* tests/data/test-lookup-syms/test01-report.txt: New.
* tests/data/test-lookup-syms/test02-report.txt: New.
* tests/data/test-read-dwarf/test0.abi: Adjust.
* tests/data/test-read-dwarf/test1.abi: Adjust.
* tests/data/test-diff-dwarf/test7-report.txt: Adjust.
* tests/data/test-diff-filter/test10-report.txt: Adjust.
* tests/data/test-diff-filter/test12-report.txt: Adjust.
* tests/data/test-lookup-syms/test1-[123]-report.txt: New.
* tests/data/test-lookup-syms/test1.c: New.
* tests/data/test-lookup-syms/test1.version-script: New.
* tests/test-lookup-syms.cc: Adjust for new tests.
* test/Makefile.am: Adjust makefile.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-05-08 09:31:57 +00:00
|
|
|
{
|
|
|
|
"data/test-lookup-syms/test1.so",
|
|
|
|
"foo",
|
|
|
|
"",
|
|
|
|
"data/test-lookup-syms/test1-1-report.txt",
|
|
|
|
"output/test-lookup-syms/test1-1-report.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-lookup-syms/test1.so",
|
|
|
|
"_foo1",
|
|
|
|
"--no-absolute-path",
|
|
|
|
"data/test-lookup-syms/test1-2-report.txt",
|
|
|
|
"output/test-lookup-syms/test-2-report.txt"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data/test-lookup-syms/test1.so",
|
|
|
|
"_foo2",
|
|
|
|
"--no-absolute-path",
|
|
|
|
"data/test-lookup-syms/test1-3-report.txt",
|
|
|
|
"output/test-lookup-syms/test-3-report.txt"
|
|
|
|
},
|
2014-08-15 16:28:22 +00:00
|
|
|
// This should always be the last entry.
|
2014-04-21 15:43:15 +00:00
|
|
|
{NULL, NULL, NULL, NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
int
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
using abigail::tests::get_src_dir;
|
|
|
|
using abigail::tests::get_build_dir;
|
2015-01-08 10:34:03 +00:00
|
|
|
using abigail::tools_utils::ensure_parent_dir_created;
|
2014-04-21 15:43:15 +00:00
|
|
|
|
|
|
|
bool is_ok = true;
|
2014-09-26 08:58:16 +00:00
|
|
|
string in_elf_path, symbol, abisym, abisym_options,
|
2014-04-21 15:43:15 +00:00
|
|
|
ref_report_path, out_report_path;
|
|
|
|
|
|
|
|
for (InOutSpec* s = in_out_specs; s->in_elf_path; ++s)
|
|
|
|
{
|
2016-01-15 12:34:16 +00:00
|
|
|
in_elf_path = string(get_src_dir()) + "/tests/" + s->in_elf_path;
|
2014-04-21 15:43:15 +00:00
|
|
|
symbol = s->symbol;
|
2014-09-26 08:58:16 +00:00
|
|
|
abisym_options = s->abisym_options;
|
2016-01-15 12:34:16 +00:00
|
|
|
ref_report_path = string(get_src_dir()) + "/tests/" + s->in_report_path;
|
|
|
|
out_report_path =
|
|
|
|
string(get_build_dir()) + "/tests/" + s->out_report_path;
|
2014-04-21 15:43:15 +00:00
|
|
|
|
|
|
|
if (!ensure_parent_dir_created(out_report_path))
|
|
|
|
{
|
|
|
|
cerr << "could not create parent directory for "
|
|
|
|
<< out_report_path;
|
|
|
|
is_ok = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-01-15 12:34:16 +00:00
|
|
|
abisym = string(get_build_dir()) + "/tools/abisym";
|
2014-09-26 08:58:16 +00:00
|
|
|
abisym += " " + abisym_options;
|
2014-04-21 15:43:15 +00:00
|
|
|
|
2014-09-26 08:58:16 +00:00
|
|
|
string cmd = abisym + " " + in_elf_path + " " + symbol;
|
2014-04-21 15:43:15 +00:00
|
|
|
cmd += " > " + out_report_path;
|
|
|
|
|
2014-09-26 08:58:16 +00:00
|
|
|
bool abisym_ok = true;
|
2014-04-21 15:43:15 +00:00
|
|
|
if (system(cmd.c_str()))
|
2014-09-26 08:58:16 +00:00
|
|
|
abisym_ok = false;
|
2014-04-21 15:43:15 +00:00
|
|
|
|
2014-09-26 08:58:16 +00:00
|
|
|
if (abisym_ok)
|
2014-04-21 15:43:15 +00:00
|
|
|
{
|
|
|
|
cmd = "diff -u " + ref_report_path + " "+ out_report_path;
|
|
|
|
if (system(cmd.c_str()))
|
|
|
|
is_ok = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
is_ok = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !is_ok;
|
|
|
|
}
|