mirror of
git://sourceware.org/git/libabigail.git
synced 2025-03-05 22:27:34 +00:00
Don't require all version symbol sections to present
When we need to get the version of a defined symbol, only the SHT_GNU_versym and SHT_GNU_verdef sections are necessary. SHT_GNU_verneed is not necessary, for instance. So do not require that all of the three version-related sections to be present when we want to get some symbol version information. Otherwise, we just don't get the version of a defined symbol when the SHT_GNU_verneed section is not present. I stumbled upon this while looking the abidw's output of ld-2.17.so from glibc-2.17-79.el7_1.x86_64. The _rtld_global_ro variable's symbol was being seen as having no symbol version. In reality it has the GLIBC_PRIVATE version, but because the binary lacks a SHT_GNU_verneed section, we were not getting the symbols version information. I am not adding that library to the test suite because it's too big. But at least this change doesn't break the existing regression test suite. * src/abg-dwarf-reader.cc (get_symbol_versionning_sections): Allow returning just some of the three version-related section, not necessarily all of them. Adjust comment. (get_version_for_symbol): Be ready to not necessarily having the three version-related sections available. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
b36ca1501e
commit
5fe6a7404b
@ -1004,13 +1004,16 @@ compare_symbol_name(const string& symbol_name,
|
||||
///
|
||||
/// @param elf_handle the elf handle to use.
|
||||
///
|
||||
/// @param versym_section the SHT_GNU_versym section found.
|
||||
/// @param versym_section the SHT_GNU_versym section found. If the
|
||||
/// section wasn't found, this is set to nil.
|
||||
///
|
||||
/// @param verdef_section the SHT_GNU_verdef section found.
|
||||
/// @param verdef_section the SHT_GNU_verdef section found. If the
|
||||
/// section wasn't found, this is set to nil.
|
||||
///
|
||||
/// @param verneed_section the SHT_GNU_verneed section found.
|
||||
/// @param verneed_section the SHT_GNU_verneed section found. If the
|
||||
/// section wasn't found, this is set to nil.
|
||||
///
|
||||
/// @return true iff the sections where found.
|
||||
/// @return true iff at least one of the the sections where found.
|
||||
static bool
|
||||
get_symbol_versionning_sections(Elf* elf_handle,
|
||||
Elf_Scn*& versym_section,
|
||||
@ -1030,14 +1033,15 @@ get_symbol_versionning_sections(Elf* elf_handle,
|
||||
verdef = section;
|
||||
else if (h->sh_type == SHT_GNU_verneed)
|
||||
verneed = section;
|
||||
}
|
||||
|
||||
if (versym && verdef && verneed)
|
||||
{
|
||||
versym_section = versym;
|
||||
verdef_section = verdef;
|
||||
verneed_section = verneed;
|
||||
return true;
|
||||
}
|
||||
if (versym || verdef || verneed)
|
||||
{
|
||||
// At least one the versionning sections was found. Return it.
|
||||
versym_section = versym;
|
||||
verdef_section = verdef;
|
||||
verneed_section = verneed;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -1206,9 +1210,14 @@ get_version_for_symbol(Elf* elf_handle,
|
||||
verneed_section))
|
||||
return false;
|
||||
|
||||
Elf_Data* versym_data = elf_getdata(versym_section, NULL);
|
||||
GElf_Versym versym_mem;
|
||||
GElf_Versym* versym = gelf_getversym(versym_data, symbol_index, &versym_mem);
|
||||
Elf_Data* versym_data = (versym_section)
|
||||
? elf_getdata(versym_section, NULL)
|
||||
: NULL;
|
||||
GElf_Versym* versym = (versym_data)
|
||||
? gelf_getversym(versym_data, symbol_index, &versym_mem)
|
||||
: NULL;
|
||||
|
||||
if (versym == 0 || *versym <= 1)
|
||||
// I got these value from the code of readelf.c in elfutils.
|
||||
// Apparently, if the symbol version entry has these values, the
|
||||
@ -1224,14 +1233,16 @@ get_version_for_symbol(Elf* elf_handle,
|
||||
// specification.
|
||||
return false;
|
||||
|
||||
if (get_version_definition_for_versym(elf_handle, versym,
|
||||
verdef_section, version))
|
||||
if (verdef_section
|
||||
&& get_version_definition_for_versym(elf_handle, versym,
|
||||
verdef_section, version))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (get_version_needed_for_versym(elf_handle, versym,
|
||||
verneed_section, version))
|
||||
if (verneed_section
|
||||
&& get_version_needed_for_versym(elf_handle, versym,
|
||||
verneed_section, version))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3372,9 +3383,14 @@ public:
|
||||
verneed_section))
|
||||
return false;
|
||||
|
||||
Elf_Data* versym_data = elf_getdata(versym_section, NULL);
|
||||
GElf_Versym versym_mem;
|
||||
GElf_Versym* versym = gelf_getversym(versym_data, symbol_index, &versym_mem);
|
||||
Elf_Data* versym_data = (versym_section)
|
||||
? elf_getdata(versym_section, NULL)
|
||||
: NULL;
|
||||
GElf_Versym* versym = (versym_data)
|
||||
? gelf_getversym(versym_data, symbol_index, &versym_mem)
|
||||
: NULL;
|
||||
|
||||
if (versym == 0 || *versym <= 1)
|
||||
// I got these value from the code of readelf.c in elfutils.
|
||||
// Apparently, if the symbol version entry has these values, the
|
||||
@ -3390,14 +3406,16 @@ public:
|
||||
// specification.
|
||||
return false;
|
||||
|
||||
if (get_version_definition_for_versym(elf_handle(), versym,
|
||||
verdef_section, version))
|
||||
if (verdef_section
|
||||
&& get_version_definition_for_versym(elf_handle(), versym,
|
||||
verdef_section, version))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (get_version_needed_for_versym(elf_handle(), versym,
|
||||
verneed_section, version))
|
||||
if (verneed_section
|
||||
&& get_version_needed_for_versym(elf_handle(), versym,
|
||||
verneed_section, version))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user