* elf.c (assign_file_positions_for_load_sections): Ensure bss
authorAlan Modra <amodra@gmail.com>
Fri, 29 Jun 2007 01:12:52 +0000 (01:12 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 29 Jun 2007 01:12:52 +0000 (01:12 +0000)
segments meet gABI alignment requirements.  Don't allocate
file space for bss sections in a segment also containing file
or program headers.

bfd/ChangeLog
bfd/elf.c

index cdb4784efe4d490b195917176604545e3eb09974..37782207b474b3de22a79649933da6325a77a76a 100644 (file)
@@ -1,3 +1,10 @@
+2007-06-29  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf.c (assign_file_positions_for_load_sections): Ensure bss
+       segments meet gABI alignment requirements.  Don't allocate
+       file space for bss sections in a segment also containing file
+       or program headers.
+
 2007-06-27  Alan Modra  <amodra@bigpond.net.au>
 
        * bfd.c (struct bfd): Rename "next" to "archive_next".
@@ -90,7 +97,7 @@
 
 2007-06-11  Sterling Augustine  <sterling@tensilica.com>
            Bob Wilson  <bob.wilson@acm.org>
-       
+
        * elf32-xtensa.c (extend_ebb_bounds_forward): Use renamed
        XTENSA_PROP_NO_TRANSFORM flag instead of XTENSA_PROP_INSN_NO_TRANSFORM.
        (extend_ebb_bounds_backward, compute_text_actions): Likewise.
        (compute_removed_literals): Pass new arguments to is_removable_literal.
        (is_removable_literal): Add sec, prop_table and ptblsize arguments.
        Do not remove literal if the NO_TRANSFORM property flag is set.
-       
+
 2007-05-31  Richard Sandiford  <rsandifo@nildram.co.uk>
 
        * elfxx-mips.c (mips_elf_initialize_tls_index): When processing a
index 532e6b574926dbef9427c6f06fce0823dfbfad84..a269f329ff0533c7a5dee6ddf0acccdb74e4cf54 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4327,6 +4327,8 @@ assign_file_positions_for_load_sections (bfd *abfd,
        m = m->next, p++, j++)
     {
       asection **secpp;
+      bfd_vma off_adjust;
+      bfd_boolean no_contents;
 
       /* If elf_segment_map is not from map_sections_to_segments, the
          sections may not be correctly ordered.  NOTE: sorting should
@@ -4382,11 +4384,12 @@ assign_file_positions_for_load_sections (bfd *abfd,
       else
        p->p_align = 0;
 
+      no_contents = FALSE;
+      off_adjust = 0;
       if (p->p_type == PT_LOAD
          && m->count > 0)
        {
          bfd_size_type align;
-         bfd_vma adjust;
          unsigned int align_power = 0;
 
          if (m->p_align_valid)
@@ -4413,28 +4416,38 @@ assign_file_positions_for_load_sections (bfd *abfd,
                 set via struct bfd_elf_special_section.  */
              elf_section_type (m->sections[i]) = SHT_NOBITS;
 
-         adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
-         if (adjust != 0)
+         /* Find out whether this segment contains any loadable
+            sections.  If the first section isn't loadable, the same
+            holds for any other sections.  */
+         i = 0;
+         while (elf_section_type (m->sections[i]) == SHT_NOBITS)
            {
-             /* If the first section isn't loadable, the same holds
-                for any other sections.  We don't need to align the
-                segment on disk since the segment doesn't need file
-                space.  */
-             i = 0;
-             while (elf_section_type (m->sections[i]) == SHT_NOBITS)
+             /* If a segment starts with .tbss, we need to look
+                at the next section to decide whether the segment
+                has any loadable sections.  */
+             if ((elf_section_flags (m->sections[i]) & SHF_TLS) == 0
+                 || ++i >= m->count)
                {
-                 /* If a segment starts with .tbss, we need to look
-                    at the next section to decide whether the segment
-                    has any loadable sections.  */
-                 if ((elf_section_flags (m->sections[i]) & SHF_TLS) == 0
-                     || ++i >= m->count)
-                   {
-                     adjust = 0;
-                     break;
-                   }
+                 no_contents = TRUE;
+                 break;
                }
-             off += adjust;
            }
+
+         off_adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
+         off += off_adjust;
+         if (no_contents)
+           {
+             /* We shouldn't need to align the segment on disk since
+                the segment doesn't need file space, but the gABI
+                arguably requires the alignment and glibc ld.so
+                checks it.  So to comply with the alignment
+                requirement but not waste file space, we adjust
+                p_offset for just this segment.  (OFF_ADJUST is
+                subtracted from OFF later.)  This may put p_offset
+                past the end of file, but that shouldn't matter.  */
+           }
+         else
+           off_adjust = 0;
        }
       /* Make sure the .dynamic section is the first section in the
         PT_DYNAMIC segment.  */
@@ -4455,7 +4468,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
 
       if (m->includes_filehdr)
        {
-         if (! m->p_flags_valid)
+         if (!m->p_flags_valid)
            p->p_flags |= PF_R;
          p->p_filesz = bed->s->sizeof_ehdr;
          p->p_memsz = bed->s->sizeof_ehdr;
@@ -4473,14 +4486,14 @@ assign_file_positions_for_load_sections (bfd *abfd,
                }
 
              p->p_vaddr -= off;
-             if (! m->p_paddr_valid)
+             if (!m->p_paddr_valid)
                p->p_paddr -= off;
            }
        }
 
       if (m->includes_phdrs)
        {
-         if (! m->p_flags_valid)
+         if (!m->p_flags_valid)
            p->p_flags |= PF_R;
 
          if (!m->includes_filehdr)
@@ -4491,7 +4504,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
                {
                  BFD_ASSERT (p->p_type == PT_LOAD);
                  p->p_vaddr -= off - p->p_offset;
-                 if (! m->p_paddr_valid)
+                 if (!m->p_paddr_valid)
                    p->p_paddr -= off - p->p_offset;
                }
            }
@@ -4503,14 +4516,15 @@ assign_file_positions_for_load_sections (bfd *abfd,
       if (p->p_type == PT_LOAD
          || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
        {
-         if (! m->includes_filehdr && ! m->includes_phdrs)
+         if (!m->includes_filehdr && !m->includes_phdrs)
            p->p_offset = off;
          else
            {
              file_ptr adjust;
 
              adjust = off - (p->p_offset + p->p_filesz);
-             p->p_filesz += adjust;
+             if (!no_contents)
+               p->p_filesz += adjust;
              p->p_memsz += adjust;
            }
        }
@@ -4622,7 +4636,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
                p->p_align = align;
            }
 
-         if (! m->p_flags_valid)
+         if (!m->p_flags_valid)
            {
              p->p_flags |= PF_R;
              if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0)
@@ -4631,6 +4645,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
                p->p_flags |= PF_W;
            }
        }
+      off -= off_adjust;
 
       /* Check that all sections are in a PT_LOAD segment.
         Don't check funky gdb generated core files.  */