mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-24 01:46:50 +00:00
symtab: add support for CRC values from __kcrctab
New kernels changed the format of storing CRC values from absolute symbol value to the address in __kcrctab or __kcrctab_gpl section. This change adds support for CRC values described in this format. * src/abg-elf-helpers.h (get_crc_for_symbol): Defined new helper function to extract CRC from ELF symbol. * src/abg-elf-helpers.cc (get_crc_for_symbol): Implemented this function with support of old and new CRC values format. * src/abg-symtab-reader.cc (symtab::load_): Used the new function when building CRC values map. Change-Id: I7de5c737d5caaef0c5b7b2ea0d448368889a16be Signed-off-by: Aleksei Vetrov <vvvvvv@google.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
102758ad9a
commit
c6ac7db457
@ -905,6 +905,53 @@ get_version_for_symbol(Elf* elf_handle,
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Return the CRC from the "__crc_" symbol.
|
||||
///
|
||||
/// @param elf_handle the elf handle to use.
|
||||
///
|
||||
/// @param crc_symbol symbol containing CRC value.
|
||||
///
|
||||
/// @param crc_value the CRC found for @p crc_symbol.
|
||||
///
|
||||
/// @return true iff a CRC was found for given @p crc_symbol.
|
||||
bool
|
||||
get_crc_for_symbol(Elf* elf_handle, GElf_Sym* crc_symbol, uint32_t& crc_value)
|
||||
{
|
||||
size_t crc_section_index = crc_symbol->st_shndx;
|
||||
uint64_t crc_symbol_value = crc_symbol->st_value;
|
||||
if (crc_section_index == SHN_ABS)
|
||||
{
|
||||
crc_value = crc_symbol_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
Elf_Scn* kcrctab_section = elf_getscn(elf_handle, crc_section_index);
|
||||
if (kcrctab_section == NULL)
|
||||
return false;
|
||||
|
||||
GElf_Shdr sheader_mem;
|
||||
GElf_Shdr* sheader = gelf_getshdr(kcrctab_section, &sheader_mem);
|
||||
if (sheader == NULL)
|
||||
return false;
|
||||
|
||||
Elf_Data* kcrctab_data = elf_rawdata(kcrctab_section, NULL);
|
||||
if (kcrctab_data == NULL)
|
||||
return false;
|
||||
|
||||
if (crc_symbol_value < sheader->sh_addr)
|
||||
return false;
|
||||
|
||||
size_t offset = crc_symbol_value - sheader->sh_addr;
|
||||
if (offset + sizeof(uint32_t) > kcrctab_data->d_size
|
||||
|| offset + sizeof(uint32_t) > sheader->sh_size)
|
||||
return false;
|
||||
|
||||
crc_value = *reinterpret_cast<uint32_t*>(
|
||||
reinterpret_cast<char*>(kcrctab_data->d_buf) + offset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Test if the architecture of the current binary is ppc64.
|
||||
///
|
||||
/// @param elf_handle the ELF handle to consider.
|
||||
|
@ -141,6 +141,9 @@ get_version_for_symbol(Elf* elf_handle,
|
||||
bool get_def_version,
|
||||
elf_symbol::version& version);
|
||||
|
||||
bool
|
||||
get_crc_for_symbol(Elf* elf_handle, GElf_Sym* crc_symbol, uint32_t& crc_value);
|
||||
|
||||
//
|
||||
// Architecture specific helpers
|
||||
//
|
||||
|
@ -314,7 +314,10 @@ symtab::load_(Elf* elf_handle,
|
||||
}
|
||||
if (is_kernel && name.rfind("__crc_", 0) == 0)
|
||||
{
|
||||
ABG_ASSERT(crc_values.emplace(name.substr(6), sym->st_value).second);
|
||||
uint32_t crc_value;
|
||||
ABG_ASSERT(elf_helpers::get_crc_for_symbol(elf_handle,
|
||||
sym, crc_value));
|
||||
ABG_ASSERT(crc_values.emplace(name.substr(6), crc_value).second);
|
||||
continue;
|
||||
}
|
||||
if (strings_section && is_kernel && name.rfind("__kstrtabns_", 0) == 0)
|
||||
|
Loading…
Reference in New Issue
Block a user