mirror of
git://sourceware.org/git/libabigail.git
synced 2025-01-21 00:40:45 +00:00
Bug 24431 Read 32bit values when testing for the v4.19 symbol table format
Reading into uint64_t when reading the symbol table values drops the sign and subsequently offset calculations will only be correct if either the offset is positive or if the calculation overflows. Read the relative value as signed int32_t (indepently of the target's bitness) to allow negative offsets. That also allows to drop the code that formerly handled the overflow. That change fixes an assertion raised when dealing with aarch64 kernel binaries that have a __ksymtab with 32bit relocations. i.e. Bug #24431 * src/abg-dwarf-reader.cc (try_reading_first_ksymtab_entry_using_v4_19_format): attempt to read first __ksymtab entry into int32_t to preserve sign Signed-off-by: Matthias Maennich <maennich@google.com>
This commit is contained in:
parent
2af6990560
commit
a8bec92de2
@ -7234,29 +7234,17 @@ public:
|
|||||||
uint8_t *bytes = reinterpret_cast<uint8_t*>(elf_data->d_buf);
|
uint8_t *bytes = reinterpret_cast<uint8_t*>(elf_data->d_buf);
|
||||||
bool is_big_endian = elf_architecture_is_big_endian();
|
bool is_big_endian = elf_architecture_is_big_endian();
|
||||||
elf_symbol_sptr symbol;
|
elf_symbol_sptr symbol;
|
||||||
unsigned char symbol_value_size = 4;
|
|
||||||
unsigned char arch_word_size = architecture_word_size();
|
|
||||||
|
|
||||||
|
int32_t offset = 0;
|
||||||
|
const unsigned char symbol_value_size = sizeof(offset);
|
||||||
GElf_Addr symbol_address = 0, adjusted_symbol_address = 0;
|
GElf_Addr symbol_address = 0, adjusted_symbol_address = 0;
|
||||||
ABG_ASSERT(read_int_from_array_of_bytes(bytes,
|
ABG_ASSERT(read_int_from_array_of_bytes(bytes,
|
||||||
symbol_value_size,
|
symbol_value_size,
|
||||||
is_big_endian,
|
is_big_endian,
|
||||||
symbol_address));
|
offset));
|
||||||
GElf_Shdr mem;
|
GElf_Shdr mem;
|
||||||
GElf_Shdr *section_header = gelf_getshdr(section, &mem);
|
GElf_Shdr *section_header = gelf_getshdr(section, &mem);
|
||||||
if (arch_word_size == 4)
|
symbol_address = offset + section_header->sh_addr;
|
||||||
symbol_address = (uint32_t)(symbol_address + section_header->sh_addr);
|
|
||||||
else if (arch_word_size == 8)
|
|
||||||
{
|
|
||||||
symbol_address = symbol_address + section_header->sh_addr;
|
|
||||||
if (symbol_address < ((uint64_t)1 << 32))
|
|
||||||
// The symbol address is expressed in 32 bits. So let's
|
|
||||||
// convert it to a 64 bits address with the 4 most
|
|
||||||
// significant bytes set to ff each.
|
|
||||||
symbol_address = ((uint64_t)0xffffffff << 32) | symbol_address;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ABG_ASSERT_NOT_REACHED;
|
|
||||||
|
|
||||||
adjusted_symbol_address = maybe_adjust_fn_sym_address(symbol_address);
|
adjusted_symbol_address = maybe_adjust_fn_sym_address(symbol_address);
|
||||||
symbol = lookup_elf_symbol_from_address(adjusted_symbol_address);
|
symbol = lookup_elf_symbol_from_address(adjusted_symbol_address);
|
||||||
|
Loading…
Reference in New Issue
Block a user