[PATCH 4/5] readelf: Consolidate get_[32|64]bit_elf_symbols
H.J. Lu
hjl.tools@gmail.com
Thu Jul 9 12:40:51 GMT 2026
Consolidate get_32bit_elf_symbols and get_64bit_elf_symbols into
get_elf_symbols. Use BYTE_GET_SIZE to retrieve external symbol
table fields.
PR binutils/34356
* readelf.c (get_32bit_elf_symbols): Renamed to ...
(get_elf_symbols): This. Updated to support 64-bit symbol table.
(get_64bit_elf_symbols): Removed.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
binutils/readelf.c | 167 +++++++--------------------------------------
1 file changed, 26 insertions(+), 141 deletions(-)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 21a237b52a7..fe87467a032 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -8021,12 +8021,12 @@ get_section_headers (Filedata *filedata, bool probe)
}
static Elf_Internal_Sym *
-get_32bit_elf_symbols (Filedata *filedata,
- Elf_Internal_Shdr *section,
- uint64_t *num_syms_return)
+get_elf_symbols (Filedata *filedata,
+ Elf_Internal_Shdr *section,
+ uint64_t *num_syms_return)
{
uint64_t number = 0;
- Elf32_External_Sym * esyms = NULL;
+ void * esyms = NULL, * ptr;
Elf_External_Sym_Shndx * shndx = NULL;
Elf_Internal_Sym * isyms = NULL;
Elf_Internal_Sym * psym;
@@ -8059,7 +8059,13 @@ get_32bit_elf_symbols (Filedata *filedata,
number = section->sh_size / section->sh_entsize;
- if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
+ unsigned int sizeof_External_Sym;
+ if (is_32bit_elf)
+ sizeof_External_Sym = sizeof (Elf32_External_Sym);
+ else
+ sizeof_External_Sym = sizeof (Elf64_External_Sym);
+
+ if (number * sizeof_External_Sym > section->sh_size + 1)
{
error (_("Size (%#" PRIx64 ") of section %s "
"is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
@@ -8069,8 +8075,8 @@ get_32bit_elf_symbols (Filedata *filedata,
goto exit_point;
}
- esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
- section->sh_size, _("symbols"));
+ esyms = get_data (NULL, filedata, section->sh_offset, 1,
+ section->sh_size, _("symbols"));
if (esyms == NULL)
goto exit_point;
@@ -8112,138 +8118,28 @@ get_32bit_elf_symbols (Filedata *filedata,
goto exit_point;
}
+ ptr = esyms;
for (j = 0, psym = isyms; j < number; j++, psym++)
{
- psym->st_name = BYTE_GET (esyms[j].st_name);
- psym->st_value = BYTE_GET (esyms[j].st_value);
- psym->st_size = BYTE_GET (esyms[j].st_size);
- psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
- if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
- psym->st_shndx
- = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
- else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
- psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
- psym->st_info = BYTE_GET (esyms[j].st_info);
- psym->st_other = BYTE_GET (esyms[j].st_other);
- }
-
- exit_point:
- free (shndx);
- free (esyms);
-
- if (num_syms_return != NULL)
- * num_syms_return = isyms == NULL ? 0 : number;
-
- return isyms;
-}
-
-static Elf_Internal_Sym *
-get_64bit_elf_symbols (Filedata *filedata,
- Elf_Internal_Shdr *section,
- uint64_t *num_syms_return)
-{
- uint64_t number = 0;
- Elf64_External_Sym * esyms = NULL;
- Elf_External_Sym_Shndx * shndx = NULL;
- Elf_Internal_Sym * isyms = NULL;
- Elf_Internal_Sym * psym;
- unsigned int j;
- elf_section_list * entry;
-
- if (section->sh_size == 0)
- {
- if (num_syms_return != NULL)
- * num_syms_return = 0;
- return NULL;
- }
-
- /* Run some sanity checks first. */
- if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
- {
- error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
- printable_section_name (filedata, section),
- section->sh_entsize);
- goto exit_point;
- }
-
- if (section->sh_size > filedata->file_size)
- {
- error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
- printable_section_name (filedata, section),
- section->sh_size);
- goto exit_point;
- }
-
- number = section->sh_size / section->sh_entsize;
-
- if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
- {
- error (_("Size (%#" PRIx64 ") of section %s "
- "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
- section->sh_size,
- printable_section_name (filedata, section),
- section->sh_entsize);
- goto exit_point;
- }
-
- esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
- section->sh_size, _("symbols"));
- if (!esyms)
- goto exit_point;
-
- shndx = NULL;
- for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
- {
- if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
- continue;
-
- if (shndx != NULL)
+ BYTE_GET_SIZE (psym->st_name, ptr, 4);
+ if (is_32bit_elf)
{
- error (_("Multiple symbol table index sections associated with the same symbol section\n"));
- free (shndx);
+ BYTE_GET_SIZE (psym->st_value, ptr, 4);
+ BYTE_GET_SIZE (psym->st_size, ptr, 4);
}
-
- shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
- entry->hdr->sh_offset,
- 1, entry->hdr->sh_size,
- _("symbol table section indices"));
- if (shndx == NULL)
- goto exit_point;
-
- /* PR17531: file: heap-buffer-overflow */
- if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
- {
- error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
- printable_section_name (filedata, entry->hdr),
- entry->hdr->sh_size,
- section->sh_size);
- goto exit_point;
- }
- }
-
- isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
-
- if (isyms == NULL)
- {
- error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
- goto exit_point;
- }
-
- for (j = 0, psym = isyms; j < number; j++, psym++)
- {
- psym->st_name = BYTE_GET (esyms[j].st_name);
- psym->st_info = BYTE_GET (esyms[j].st_info);
- psym->st_other = BYTE_GET (esyms[j].st_other);
- psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
-
+ BYTE_GET_SIZE (psym->st_info, ptr, 1);
+ BYTE_GET_SIZE (psym->st_other, ptr, 1);
+ BYTE_GET_SIZE (psym->st_shndx, ptr, 2);
if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
psym->st_shndx
= byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
-
- psym->st_value = BYTE_GET (esyms[j].st_value);
- psym->st_size = BYTE_GET (esyms[j].st_size);
+ if (!is_32bit_elf)
+ {
+ BYTE_GET_SIZE (psym->st_value, ptr, 8);
+ BYTE_GET_SIZE (psym->st_size, ptr, 8);
+ }
}
exit_point:
@@ -8256,17 +8152,6 @@ get_64bit_elf_symbols (Filedata *filedata,
return isyms;
}
-static Elf_Internal_Sym *
-get_elf_symbols (Filedata *filedata,
- Elf_Internal_Shdr *section,
- uint64_t *num_syms_return)
-{
- if (is_32bit_elf)
- return get_32bit_elf_symbols (filedata, section, num_syms_return);
- else
- return get_64bit_elf_symbols (filedata, section, num_syms_return);
-}
-
static const char *
get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
{
--
2.55.0
More information about the Binutils
mailing list