mirror of
git://sourceware.org/git/libabigail.git
synced 2025-03-06 14:47:32 +00:00
dwarf-reader: refactor try_reading_first_ksymtab_entry_using{pre,}_v4_19_format
Avoid code duplication and increase maintainebility of these helper functions. As their only difference was the application of position relative relocations, consolidate them and add a flag for exactly this feature. This is purely stylistic and not changing functionality. * src/abg-dwarf-reader.cc(try_reading_first_ksymtab_entry): New function to consolidate functionality for try_reading_first_ksymtab_entry_using_{pre,}v4_19_format functions. (try_reading_first_ksymtab_entry_using_v4_19_format, try_reading_first_ksymtab_entry_using_pre_v4_19_format): refactor to use try_reading_first_ksymtab_entry Signed-off-by: Matthias Maennich <maennich@google.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
847800d497
commit
43679a6103
@ -7588,67 +7588,86 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Try reading the first __ksymtab section entry.
|
||||||
|
///
|
||||||
|
/// We lookup the symbol from the raw section passed as an argument. For
|
||||||
|
/// that, consider endianess and adjust for potential Elf relocations before
|
||||||
|
/// looking up the symbol in the .symtab section.
|
||||||
|
//
|
||||||
|
/// Optionally, support position relative relocations by considering the
|
||||||
|
/// ksymtab entry as 32 bit and applying the relocation relative to the
|
||||||
|
/// section header (i.e. the symbol position as we are reading the first
|
||||||
|
/// symbol).
|
||||||
|
///
|
||||||
|
/// @return the symbol resulting from the lookup of the symbol address we
|
||||||
|
/// got from reading the first entry of the ksymtab or null if no such entry
|
||||||
|
/// could be found.
|
||||||
|
elf_symbol_sptr
|
||||||
|
try_reading_first_ksymtab_entry(Elf_Scn* section,
|
||||||
|
bool position_relative_relocations) const
|
||||||
|
{
|
||||||
|
// this function does not support relocatable ksymtab entries (as for
|
||||||
|
// example in kernel modules). Hence assert here on not having any
|
||||||
|
// relocation sections around. We can consider this a TODO that we have to
|
||||||
|
// work around in the rest of the code.
|
||||||
|
ABG_ASSERT(!find_any_ksymtab_reloc_section());
|
||||||
|
|
||||||
|
Elf_Data* elf_data = elf_rawdata(section, 0);
|
||||||
|
uint8_t* bytes = reinterpret_cast<uint8_t*>(elf_data->d_buf);
|
||||||
|
bool is_big_endian = elf_architecture_is_big_endian();
|
||||||
|
elf_symbol_sptr symbol;
|
||||||
|
GElf_Addr symbol_address = 0;
|
||||||
|
|
||||||
|
unsigned char symbol_value_size;
|
||||||
|
if (position_relative_relocations)
|
||||||
|
symbol_value_size = sizeof(int32_t);
|
||||||
|
else
|
||||||
|
symbol_value_size = architecture_word_size();
|
||||||
|
|
||||||
|
if (position_relative_relocations)
|
||||||
|
{
|
||||||
|
int32_t offset = 0;
|
||||||
|
ABG_ASSERT(read_int_from_array_of_bytes(bytes, symbol_value_size,
|
||||||
|
is_big_endian, offset));
|
||||||
|
GElf_Shdr section_header;
|
||||||
|
gelf_getshdr(section, §ion_header);
|
||||||
|
symbol_address = offset + section_header.sh_addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ABG_ASSERT(read_int_from_array_of_bytes(bytes, symbol_value_size,
|
||||||
|
is_big_endian, symbol_address));
|
||||||
|
|
||||||
|
symbol_address = maybe_adjust_fn_sym_address(symbol_address);
|
||||||
|
symbol = lookup_elf_symbol_from_address(symbol_address);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
/// Try reading the first __ksymtab section entry as if it is in the
|
/// Try reading the first __ksymtab section entry as if it is in the
|
||||||
/// pre-v4_19 format and lookup a symbol from the .symbol section to
|
/// pre-v4_19 format, that is without position relative relocations.
|
||||||
/// see if that succeeds. If it does, then we can assume the
|
|
||||||
/// __ksymtab section is in the pre-v4_19 format.
|
|
||||||
///
|
///
|
||||||
/// @return the symbol resulting from the lookup of the symbol
|
/// @return the symbol resulting from the lookup of the symbol
|
||||||
/// address we got from reading the first entry of the ksymtab
|
/// address we got from reading the first entry of the ksymtab
|
||||||
/// section assuming the pre-v4.19 format. If nil, it means the
|
/// section assuming the pre-v4.19 format. If null, it means the
|
||||||
/// __ksymtab section is not in the pre-v4.19 format.
|
/// __ksymtab section is not in the pre-v4.19 format.
|
||||||
elf_symbol_sptr
|
elf_symbol_sptr
|
||||||
try_reading_first_ksymtab_entry_using_pre_v4_19_format() const
|
try_reading_first_ksymtab_entry_using_pre_v4_19_format() const
|
||||||
{
|
{
|
||||||
Elf_Scn *section = find_any_ksymtab_section();
|
Elf_Scn *section = find_any_ksymtab_section();
|
||||||
Elf_Data *elf_data = elf_rawdata(section, 0);
|
return try_reading_first_ksymtab_entry(section, false);
|
||||||
uint8_t *bytes = reinterpret_cast<uint8_t*>(elf_data->d_buf);
|
|
||||||
bool is_big_endian = elf_architecture_is_big_endian();
|
|
||||||
elf_symbol_sptr symbol;
|
|
||||||
unsigned char symbol_value_size = architecture_word_size();
|
|
||||||
|
|
||||||
GElf_Addr symbol_address = 0, adjusted_symbol_address = 0;
|
|
||||||
ABG_ASSERT(read_int_from_array_of_bytes(bytes,
|
|
||||||
symbol_value_size,
|
|
||||||
is_big_endian,
|
|
||||||
symbol_address));
|
|
||||||
adjusted_symbol_address = maybe_adjust_fn_sym_address(symbol_address);
|
|
||||||
symbol = lookup_elf_symbol_from_address(adjusted_symbol_address);
|
|
||||||
return symbol;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try reading the first __ksymtab section entry as if it is in the
|
/// Try reading the first __ksymtab section entry as if it is in the
|
||||||
/// v4_19 format and lookup a symbol from the .symbol section to see
|
/// v4_19 format, that is with position relative relocations.
|
||||||
/// if that succeeds. If it does, then we can assume the __ksymtab
|
|
||||||
/// section is in the v4_19 format.
|
|
||||||
///
|
///
|
||||||
/// @return the symbol resulting from the lookup of the symbol
|
/// @return the symbol resulting from the lookup of the symbol
|
||||||
/// address we got from reading the first entry of the ksymtab
|
/// address we got from reading the first entry of the ksymtab
|
||||||
/// section assuming the v4.19 format. If nil, it means the
|
/// section assuming the v4.19 format. If null, it means the
|
||||||
/// __ksymtab section is not in the v4.19 format.
|
/// __ksymtab section is not in the v4.19 format.
|
||||||
elf_symbol_sptr
|
elf_symbol_sptr
|
||||||
try_reading_first_ksymtab_entry_using_v4_19_format() const
|
try_reading_first_ksymtab_entry_using_v4_19_format() const
|
||||||
{
|
{
|
||||||
Elf_Scn *section = find_any_ksymtab_section();
|
Elf_Scn *section = find_any_ksymtab_section();
|
||||||
Elf_Data *elf_data = elf_rawdata(section, 0);
|
return try_reading_first_ksymtab_entry(section, true);
|
||||||
uint8_t *bytes = reinterpret_cast<uint8_t*>(elf_data->d_buf);
|
|
||||||
bool is_big_endian = elf_architecture_is_big_endian();
|
|
||||||
elf_symbol_sptr symbol;
|
|
||||||
|
|
||||||
int32_t offset = 0;
|
|
||||||
const unsigned char symbol_value_size = sizeof(offset);
|
|
||||||
GElf_Addr symbol_address = 0, adjusted_symbol_address = 0;
|
|
||||||
ABG_ASSERT(read_int_from_array_of_bytes(bytes,
|
|
||||||
symbol_value_size,
|
|
||||||
is_big_endian,
|
|
||||||
offset));
|
|
||||||
GElf_Shdr mem;
|
|
||||||
GElf_Shdr *section_header = gelf_getshdr(section, &mem);
|
|
||||||
symbol_address = offset + section_header->sh_addr;
|
|
||||||
|
|
||||||
adjusted_symbol_address = maybe_adjust_fn_sym_address(symbol_address);
|
|
||||||
symbol = lookup_elf_symbol_from_address(adjusted_symbol_address);
|
|
||||||
return symbol;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to determine the format of the __ksymtab and __ksymtab_gpl
|
/// Try to determine the format of the __ksymtab and __ksymtab_gpl
|
||||||
|
Loading…
Reference in New Issue
Block a user