Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symtab refactor #1

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a5d02b9
Bug 26127 - abidw --annotate emits incomplete function types
Jun 18, 2020
5f1945b
get_canonical_type_for: restore environment better
myxoid Jun 17, 2020
df47240
Improve code comments and whitespace.
myxoid Jun 10, 2020
56db287
Refactor d.context() as ctxt in report(enum_diff).
myxoid Jun 10, 2020
2b2f073
Tidy build_enum_type state variables.
myxoid Jun 10, 2020
dd1c608
Rename declaration-definition change category.
myxoid Jun 29, 2020
db88763
abg-cxx-compat: add simplified version of std::optional
metti Apr 28, 2020
3be8a10
abg-cxx-compat: more <functional> support: std::bind and friends
metti Apr 29, 2020
4fba0c2
abg-ir: elf_symbol: add is_in_ksymtab field
metti Apr 29, 2020
f515490
abg-ir: elf_symbol: add is_suppressed field
metti Jun 8, 2020
3a34228
dwarf-reader split: create abg-symtab-reader.{h,cc} and test case
metti Apr 13, 2020
c8bccd4
Refactor ELF symbol table reading by adding a new symtab reader
metti Apr 29, 2020
b28ecc7
Integrate new symtab reader into corpus and read_context
metti May 19, 2020
a330a1d
corpus: make get_(undefined_)?_(var|fun)_symbols use the new symtab
metti Apr 30, 2020
197b11b
corpus: make get_unreferenced_(function|variable)_symbols use the new…
metti May 4, 2020
554d990
abg-reader: avoid using the (var|function)_symbol_map
metti May 4, 2020
a880ff8
dwarf-reader: read_context: use new symtab in *_symbols_is_exported
metti May 6, 2020
ec12acb
Switch kernel stuff over to new symtab and drop unused code
metti May 6, 2020
46a8880
abg-elf-helpers: migrate ppc64 specific helpers
metti May 11, 2020
176bdd5
symtab_reader: add support for ppc64 ELFv1 binaries
metti May 14, 2020
6c9fe81
abg-corpus: remove symbol maps and their setters
metti May 20, 2020
ccadb62
dwarf reader: drop now-unused code related to symbol table reading
metti Jun 2, 2020
12b74a3
test-symtab: add tests for whitelisted functions
metti Jun 29, 2020
8379985
symtab/dwarf-reader: allow hinting of main symbols for aliases
metti Jun 30, 2020
c59aada
dwarf-reader/writer: consider aliases when dealing with suppressions
metti Jun 28, 2020
de78448
symtab: Add support for MODVERSIONS (CRC checksums)
metti Jun 30, 2020
dd0428c
reader/symtab: Improve handling for suppressed aliases
metti Jul 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
symtab_reader: add support for ppc64 ELFv1 binaries
When loading the symtab from an ppc64 binary, also keep track of the
function entry addresses as a key for the symbol lookup. That
accommodates the differences in DWARF pointing to the function entry
address while the symbol table points to the function pointer.

The implementation is mostly copied and adopted from abg-dwarf-reader's
read_context to add this functionality also to the new symtab reader.

	* src/abg-symtab-reader.cc (symtab::lookup_symbol): fall back to
	  lookup the address in entry_addr_symbol_map_.
	  (symtab::load): update the function entry address map for
	  ppc64 targets.
	  (symtab::update_function_entry_address_symbol_map): New
	  function implementation.
	* src/abg-symtab-reader.h
	  (symtab::entry_addr_symbol_map_): New data member.
	  (symtab::update_function_entry_address_symbol_map): New
	  function declaration.

Reviewed-by: Giuliano Procida <gprocida@google.com>
Signed-off-by: Matthias Maennich <maennich@google.com>
  • Loading branch information
metti committed Jul 2, 2020
commit 176bdd51b415353dae771d0b60018e4ed3ee8aab
8 changes: 8 additions & 0 deletions include/abg-symtab-reader.h
Original file line number Diff line number Diff line change
@@ -342,6 +342,9 @@ class symtab
addr_symbol_map_type;
addr_symbol_map_type addr_symbol_map_;

/// Lookup map function entry address -> symbol
addr_symbol_map_type entry_addr_symbol_map_;

/// Load the symtab representation from an Elf binary presented to us by an
/// Elf* handle.
///
@@ -366,6 +369,11 @@ class symtab
bool
load_(string_elf_symbols_map_sptr function_symbol_map,
string_elf_symbols_map_sptr variables_symbol_map);

void
update_function_entry_address_symbol_map(Elf* elf_handle,
GElf_Sym* native_symbol,
const elf_symbol_sptr& symbol_sptr);
};

/// Helper class to allow range-for loops on symtabs for C++11 and later code.
93 changes: 90 additions & 3 deletions src/abg-symtab-reader.cc
Original file line number Diff line number Diff line change
@@ -91,11 +91,16 @@ const elf_symbol_sptr&
symtab::lookup_symbol(GElf_Addr symbol_addr) const
{
static const elf_symbol_sptr empty_result;
const addr_symbol_map_type::const_iterator it =
const addr_symbol_map_type::const_iterator addr_it =
addr_symbol_map_.find(symbol_addr);
if (it != addr_symbol_map_.end())
if (addr_it != addr_symbol_map_.end())
return addr_it->second;
else
{
return it->second;
const addr_symbol_map_type::const_iterator entry_it =
entry_addr_symbol_map_.find(symbol_addr);
if (entry_it != entry_addr_symbol_map_.end())
return entry_it->second;
}
return empty_result;
}
@@ -172,6 +177,8 @@ symtab::load_(Elf* elf_handle,
const bool is_kernel = elf_helpers::is_linux_kernel(elf_handle);
abg_compat::unordered_set<std::string> exported_kernel_symbols;

const bool is_ppc64 = elf_helpers::architecture_is_ppc64(elf_handle);

for (size_t i = 0; i < number_syms; ++i)
{
GElf_Sym *sym, sym_mem;
@@ -277,6 +284,10 @@ symtab::load_(Elf* elf_handle,
elf_helpers::maybe_adjust_et_rel_sym_addr_to_abs_addr(elf_handle,
sym);

if (is_ppc64 && symbol_sptr->is_function())
update_function_entry_address_symbol_map(elf_handle, sym,
symbol_sptr);

const std::pair<addr_symbol_map_type::const_iterator, bool> result =
addr_symbol_map_.insert(
std::make_pair(symbol_value, symbol_sptr));
@@ -345,5 +356,81 @@ symtab::load_(string_elf_symbols_map_sptr function_symbol_map,
return true;
}

void
symtab::update_function_entry_address_symbol_map(
Elf* elf_handle,
GElf_Sym* native_symbol,
const elf_symbol_sptr& symbol_sptr)
{

// For ppc64 ELFv1 binaries, we need to build a function entry point address
// -> function symbol map. This is in addition to the function pointer ->
// symbol map. This is because on ppc64 ELFv1, a function pointer is
// different from a function entry point address.
//
// On ppc64 ELFv1, the DWARF DIE of a function references the address of the
// entry point of the function symbol; whereas the value of the function
// symbol is the function pointer. As these addresses are different, if I we
// want to get to the symbol of a function from its entry point address (as
// referenced by DWARF function DIEs) we must have the two maps I mentionned
// right above.
//
// In other words, we need a map that associates a function entry point
// address with the symbol of that function, to be able to get the function
// symbol that corresponds to a given function DIE, on ppc64.
//
// The value of the function pointer (the value of the symbol) usually refers
// to the offset of a table in the .opd section. But sometimes, for a symbol
// named "foo", the corresponding symbol named ".foo" (note the dot before
// foo) which value is the entry point address of the function; that entry
// point address refers to a region in the .text section.
//
// So we are only interested in values of the symbol that are in the .opd
// section.
const GElf_Addr fn_desc_addr = native_symbol->st_value;
const GElf_Addr fn_entry_point_addr =
elf_helpers::lookup_ppc64_elf_fn_entry_point_address(elf_handle,
fn_desc_addr);

const std::pair<addr_symbol_map_type::const_iterator, bool>& result =
entry_addr_symbol_map_.insert(
std::make_pair(fn_entry_point_addr, symbol_sptr));

const addr_symbol_map_type::const_iterator it = result.first;
const bool was_inserted = result.second;
if (!was_inserted
&& elf_helpers::address_is_in_opd_section(elf_handle, fn_desc_addr))
{
// Either
//
// 'symbol' must have been registered as an alias for
// it->second->get_main_symbol()
//
// Or
//
// if the name of 'symbol' is foo, then the name of it2->second is
// ".foo". That is, foo is the name of the symbol when it refers to the
// function descriptor in the .opd section and ".foo" is an internal name
// for the address of the entry point of foo.
//
// In the latter case, we just want to keep a reference to "foo" as .foo
// is an internal name.

const bool two_symbols_alias =
it->second->get_main_symbol()->does_alias(*symbol_sptr);
const bool symbol_is_foo_and_prev_symbol_is_dot_foo =
(it->second->get_name() == std::string(".") + symbol_sptr->get_name());

ABG_ASSERT(two_symbols_alias
|| symbol_is_foo_and_prev_symbol_is_dot_foo);

if (symbol_is_foo_and_prev_symbol_is_dot_foo)
// Let's just keep a reference of the symbol that the user sees in the
// source code (the one named foo). The symbol which name is prefixed
// with a "dot" is an artificial one.
entry_addr_symbol_map_[fn_entry_point_addr] = symbol_sptr;
}
}

} // end namespace symtab_reader
} // end namespace abigail