* elf.c (write_zeros): New function.
authorAlan Modra <amodra@gmail.com>
Tue, 8 Dec 2009 03:43:23 +0000 (03:43 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 8 Dec 2009 03:43:23 +0000 (03:43 +0000)
(assign_file_positions_for_load_sections): Allocate file space for
NOBITS sections that are followed by PROGBITS sections in a segment.

bfd/ChangeLog
bfd/elf.c

index 00ae4cf13014a8d528d8381f28667ecb6887ec9d..6cbee4ac7b397ac0d40ac19d7c0f68ef478a94be 100644 (file)
@@ -1,3 +1,9 @@
+2009-12-08  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf.c (write_zeros): New function.
+       (assign_file_positions_for_load_sections): Allocate file space for
+       NOBITS sections that are followed by PROGBITS sections in a segment.
+
 2009-12-03  Tristan Gingold  <gingold@adacore.com>
 
        * mach-o.c (bfd_mach_o_make_bfd_section): Force debug flags for
index 4a329294ce7c1645bbb4a881359cdd6b99316d9f..88ebf719266286af24b62ff5ef32ad01b27d94f8 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4127,6 +4127,22 @@ print_segment_map (const struct elf_segment_map *m)
   putc ('\n',stderr);
 }
 
+static bfd_boolean
+write_zeros (bfd *abfd, file_ptr pos, bfd_size_type len)
+{
+  void *buf;
+  bfd_boolean ret;
+
+  if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+    return FALSE;
+  buf = bfd_zmalloc (len);
+  if (buf == NULL)
+    return FALSE;
+  ret = bfd_bwrite (buf, len, abfd) == len;
+  free (buf);
+  return ret;
+}
+
 /* Assign file positions to the sections based on the mapping from
    sections to segments.  This function also sets up some fields in
    the file header.  */
@@ -4448,6 +4464,15 @@ assign_file_positions_for_load_sections (bfd *abfd,
 
              if (this_hdr->sh_type != SHT_NOBITS)
                {
+                 if (p->p_filesz + adjust < p->p_memsz)
+                   {
+                     /* We have a PROGBITS section following NOBITS ones.
+                        Allocate file space for the NOBITS section(s) and
+                        zero it.  */
+                     adjust = p->p_memsz - p->p_filesz;
+                     if (!write_zeros (abfd, off, adjust))
+                       return FALSE;
+                   }
                  off += adjust;
                  p->p_filesz += adjust;
                }