@@ -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. */