[PATCH 3/5] readelf: Consolidate get_[32|64]bit_program_headers
"H.J. Lu" <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <[email protected]> |
Consolidate get_32bit_program_headers and get_64bit_program_headers into get_program_headers. Use BYTE_GET_SIZE to retrieve external ELF program header fields. PR binutils/34356 * readelf.c (get_32bit_program_headers): Moved to ... (get_program_headers): This. Use BYTE_GET_SIZE to retrieve external ELF program header fields. (get_64bit_program_headers): Removed. Signed-off-by: H.J. Lu <[email protected]> --- binutils/readelf.c | 162 +++++++++++++++++---------------------------- 1 file changed, 59 insertions(+), 103 deletions(-) diff --git a/binutils/readelf.c b/binutils/readelf.c index 1e3caeec252..21a237b52a7 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -7361,100 +7361,6 @@ process_file_header (Filedata * filedata) return true; } -/* Read in the program headers from FILEDATA and store them in PHEADERS. - Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */ - -static bool -get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders) -{ - Elf32_External_Phdr * phdrs; - Elf32_External_Phdr * external; - Elf_Internal_Phdr * internal; - unsigned int i; - unsigned int size = filedata->file_header.e_phentsize; - unsigned int num = filedata->file_header.e_phnum; - - /* PR binutils/17531: Cope with unexpected section header sizes. */ - if (size == 0 || num == 0) - return false; - if (size < sizeof * phdrs) - { - error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n")); - return false; - } - if (size > sizeof * phdrs) - warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n")); - - phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff, - size, num, _("program headers")); - if (phdrs == NULL) - return false; - - for (i = 0, internal = pheaders, external = phdrs; - i < filedata->file_header.e_phnum; - i++, internal++, external++) - { - internal->p_type = BYTE_GET (external->p_type); - internal->p_offset = BYTE_GET (external->p_offset); - internal->p_vaddr = BYTE_GET (external->p_vaddr); - internal->p_paddr = BYTE_GET (external->p_paddr); - internal->p_filesz = BYTE_GET (external->p_filesz); - internal->p_memsz = BYTE_GET (external->p_memsz); - internal->p_flags = BYTE_GET (external->p_flags); - internal->p_align = BYTE_GET (external->p_align); - } - - free (phdrs); - return true; -} - -/* Read in the program headers from FILEDATA and store them in PHEADERS. - Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */ - -static bool -get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders) -{ - Elf64_External_Phdr * phdrs; - Elf64_External_Phdr * external; - Elf_Internal_Phdr * internal; - unsigned int i; - unsigned int size = filedata->file_header.e_phentsize; - unsigned int num = filedata->file_header.e_phnum; - - /* PR binutils/17531: Cope with unexpected section header sizes. */ - if (size == 0 || num == 0) - return false; - if (size < sizeof * phdrs) - { - error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n")); - return false; - } - if (size > sizeof * phdrs) - warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n")); - - phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff, - size, num, _("program headers")); - if (!phdrs) - return false; - - for (i = 0, internal = pheaders, external = phdrs; - i < filedata->file_header.e_phnum; - i++, internal++, external++) - { - internal->p_type = BYTE_GET (external->p_type); - internal->p_flags = BYTE_GET (external->p_flags); - internal->p_offset = BYTE_GET (external->p_offset); - internal->p_vaddr = BYTE_GET (external->p_vaddr); - internal->p_paddr = BYTE_GET (external->p_paddr); - internal->p_filesz = BYTE_GET (external->p_filesz); - internal->p_memsz = BYTE_GET (external->p_memsz); - internal->p_align = BYTE_GET (external->p_align); - } - - free (phdrs); - return true; -} - /* Returns TRUE if the program headers were read into `program_headers'. */ static bool @@ -7466,10 +7372,22 @@ get_program_headers (Filedata * filedata) if (filedata->program_headers != NULL) return true; + unsigned int elf_class_size; + unsigned int sizeof_External_Phdr; + if (is_32bit_elf) + { + elf_class_size = 4; + sizeof_External_Phdr = sizeof (Elf32_External_Phdr); + } + else + { + elf_class_size = 8; + sizeof_External_Phdr = sizeof (Elf64_External_Phdr); + } + /* Be kind to memory checkers by looking for e_phnum values which we know must be invalid. */ - if (filedata->file_header.e_phnum - * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr)) + if (filedata->file_header.e_phnum * sizeof_External_Phdr >= filedata->file_size) { error (_("Too many program headers - %#x - the file is not that big\n"), @@ -7486,16 +7404,54 @@ get_program_headers (Filedata * filedata) return false; } - if (is_32bit_elf - ? get_32bit_program_headers (filedata, phdrs) - : get_64bit_program_headers (filedata, phdrs)) + unsigned int i; + unsigned int size = filedata->file_header.e_phentsize; + unsigned int num = filedata->file_header.e_phnum; + void *e_phdrs, *external; + Elf_Internal_Phdr *internal; + + /* PR binutils/17531: Cope with unexpected section header sizes. */ + if (size == 0 || num == 0) + { + free (phdrs); + return false; + } + + if (size != sizeof_External_Phdr) + warn (_("The e_phentsize field (%u) in the ELF header isn't the " + "same as the size of an ELF program header (%u)\n"), + size, sizeof_External_Phdr); + + e_phdrs = get_data (NULL, filedata, filedata->file_header.e_phoff, + size, num, _("program headers")); + if (e_phdrs == NULL) { - filedata->program_headers = phdrs; - return true; + free (phdrs); + return false; } - free (phdrs); - return false; + external = e_phdrs; + for (i = 0, internal = phdrs; + i < filedata->file_header.e_phnum; + i++, internal++) + { + BYTE_GET_SIZE (internal->p_type, external, 4); + if (!is_32bit_elf) + BYTE_GET_SIZE (internal->p_flags, external, 4); + BYTE_GET_SIZE (internal->p_offset, external, elf_class_size); + BYTE_GET_SIZE (internal->p_vaddr, external, elf_class_size); + BYTE_GET_SIZE (internal->p_paddr, external, elf_class_size); + BYTE_GET_SIZE (internal->p_filesz, external, elf_class_size); + BYTE_GET_SIZE (internal->p_memsz, external, elf_class_size); + if (is_32bit_elf) + BYTE_GET_SIZE (internal->p_flags, external, 4); + BYTE_GET_SIZE (internal->p_align, external, elf_class_size); + } + + free (e_phdrs); + + filedata->program_headers = phdrs; + return true; } /* Print program header info and locate dynamic section. */ -- 2.55.0