mirror of
git://sourceware.org/git/libabigail.git
synced 2025-03-07 07:07:36 +00:00
PR25058 - Better support fn DIEs referring to symbols using DW_AT_ranges
In the previous commit 2f7248f
, we were just taking the first address
referred to by the DW_AT_ranges attribute as being the address of the
symbol of the function we are looking at. But there can be cases
where this is not true, as explained at
https://sourceware.org/bugzilla/show_bug.cgi?id=25058#c7.
We really need to get the first address that represents an exported
and defined function symbol, which is pointed to by the DW_AT_ranges
attribute.
And this is what this patch does.
* src/abg-dwarf-reader.cc
(read_context::get_first_exported_fn_address_from_DW_AT_ranges):
Rename read_context::get_first_address_from_DW_AT_ranges into
this. Walk through the addresses referred to by the DW_AT_ranges
attribute until we find one that is for an exported function
symbol, rather than just picking the first address of the set.
(read_context::get_function_address): Adjust.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
2f7248f340
commit
5b9f5efab2
@ -8565,8 +8565,8 @@ public:
|
||||
return addr;
|
||||
}
|
||||
|
||||
/// Get the first address in the set of addresses referred to by the
|
||||
/// DW_AT_ranges attribute of a given DIE.
|
||||
/// Get the first exported function address in the set of addresses
|
||||
/// referred to by the DW_AT_ranges attribute of a given DIE.
|
||||
///
|
||||
/// @param die the DIE we are considering.
|
||||
///
|
||||
@ -8576,14 +8576,29 @@ public:
|
||||
/// true. Otherwise, no value is set into this output parameter.
|
||||
///
|
||||
/// @return true iff the DIE @p die does have a DW_AT_ranges
|
||||
/// attribute and an address was found in its sequence value.
|
||||
/// attribute and an address of an exported function was found in
|
||||
/// its sequence value.
|
||||
bool
|
||||
get_first_address_from_DW_AT_ranges(Dwarf_Die* die, Dwarf_Addr& address) const
|
||||
get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
|
||||
Dwarf_Addr& address) const
|
||||
{
|
||||
Dwarf_Addr base;
|
||||
Dwarf_Addr end_addr;
|
||||
if (dwarf_ranges(die, /*offset=*/0, &base, &address, &end_addr))
|
||||
return true;
|
||||
ptrdiff_t offset = 0;
|
||||
|
||||
do
|
||||
{
|
||||
Dwarf_Addr addr, fn_addr;
|
||||
if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
|
||||
{
|
||||
fn_addr = maybe_adjust_fn_sym_address(addr);
|
||||
if (function_symbol_is_exported(fn_addr))
|
||||
{
|
||||
address = fn_addr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} while (offset > 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -8603,18 +8618,17 @@ public:
|
||||
bool
|
||||
get_function_address(Dwarf_Die* function_die, Dwarf_Addr& address) const
|
||||
{
|
||||
Dwarf_Addr fn_address = 0;
|
||||
if (!die_address_attribute(function_die, DW_AT_low_pc, fn_address))
|
||||
if (!die_address_attribute(function_die, DW_AT_low_pc, address))
|
||||
// So no DW_AT_low_pc was found. Let's see if the function DIE
|
||||
// has got a DW_AT_ranges attribute instead. If it does, the
|
||||
// first address of the set of addresses represented by the
|
||||
// value of that DW_AT_ranges represents the function (symbol)
|
||||
// address we are looking for.
|
||||
if (!get_first_address_from_DW_AT_ranges(function_die, fn_address))
|
||||
if (!get_first_exported_fn_address_from_DW_AT_ranges(function_die,
|
||||
address))
|
||||
return false;
|
||||
|
||||
fn_address = maybe_adjust_fn_sym_address(fn_address);
|
||||
address = fn_address;
|
||||
address = maybe_adjust_fn_sym_address(address);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user