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