[PATCH 4/5] readelf: Consolidate get_[32|64]bit_elf_symbols
"H.J. Lu" <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- 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