2007-09-23 Jan Kratochvil * elfcode.h (NAME(_bfd_elf,bfd_from_remote_memory)): New variables X_SHDR_SHSTRTAB and I_SHDR_SHSTRTAB. Fixed the CONTENTS_SIZE trimming check for its aligned size between the last segment and still before the section header end. Added variables check to cover also the section header string table. --- ./bfd/elfcode.h 14 Aug 2007 08:04:47 -0000 1.86 +++ ./bfd/elfcode.h 23 Sep 2007 14:24:39 -0000 @@ -1628,6 +1628,8 @@ NAME(_bfd_elf,bfd_from_remote_memory) Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ Elf_External_Phdr *x_phdrs; Elf_Internal_Phdr *i_phdrs, *last_phdr; + Elf_External_Shdr *x_shdr_shstrtab; + Elf_Internal_Shdr *i_shdr_shstrtab; bfd *nbfd; struct bfd_in_memory *bim; int contents_size; @@ -1746,19 +1748,49 @@ NAME(_bfd_elf,bfd_from_remote_memory) /* Trim the last segment so we don't bother with zeros in the last page that are off the end of the file. However, if the extra bit in that - page includes the section headers, keep them. */ - if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz - && (bfd_vma) contents_size >= (i_ehdr.e_shoff - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) - { - contents_size = last_phdr->p_offset + last_phdr->p_filesz; - if ((bfd_vma) contents_size < (i_ehdr.e_shoff - + i_ehdr.e_shnum * i_ehdr.e_shentsize)) - contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; - } - else + page includes the section headers os the section header string table, + keep them. */ + if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz) contents_size = last_phdr->p_offset + last_phdr->p_filesz; + if ((bfd_vma) contents_size < i_ehdr.e_shoff + + i_ehdr.e_shnum * i_ehdr.e_shentsize) + contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; + + /* Section header string table is usually before the section headers + so this check is here has usually no effect. */ + if (i_ehdr.e_shstrndx < i_ehdr.e_shnum) + { + x_shdr_shstrtab = bfd_malloc (sizeof *x_shdr_shstrtab + + sizeof *i_shdr_shstrtab); + if (x_shdr_shstrtab == NULL) + { + free (x_phdrs); + bfd_set_error (bfd_error_no_memory); + return NULL; + } + err = target_read_memory (ehdr_vma + i_ehdr.e_shoff + + i_ehdr.e_shstrndx * sizeof *x_shdr_shstrtab, + (bfd_byte *) x_shdr_shstrtab, + sizeof *x_shdr_shstrtab); + if (err) + { + free (x_shdr_shstrtab); + free (x_phdrs); + bfd_set_error (bfd_error_system_call); + errno = err; + return NULL; + } + i_shdr_shstrtab = (Elf_Internal_Shdr *) &x_shdr_shstrtab[1]; + elf_swap_shdr_in (templ, x_shdr_shstrtab, i_shdr_shstrtab); + + if ((bfd_vma) contents_size < i_shdr_shstrtab->sh_offset + + i_shdr_shstrtab->sh_size) + contents_size = i_shdr_shstrtab->sh_offset + i_shdr_shstrtab->sh_size; + + free (x_shdr_shstrtab); + } + /* Now we know the size of the whole image we want read in. */ contents = bfd_zmalloc (contents_size); if (contents == NULL)