* elf.c (assign_file_positions_for_load_sections): Correct sh_type
authorAlan Modra <amodra@gmail.com>
Wed, 30 May 2007 13:38:50 +0000 (13:38 +0000)
committerAlan Modra <amodra@gmail.com>
Wed, 30 May 2007 13:38:50 +0000 (13:38 +0000)
to SHT_NOBITS earlier.  Base actions in rest of function on sh_type
and sh_flags instead of bfd section flags.  Delete voff and code
keeping nobits segments aligned.

bfd/ChangeLog
bfd/elf.c

index 37c21dd..01d0436 100644 (file)
@@ -1,3 +1,10 @@
+2007-05-30  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf.c (assign_file_positions_for_load_sections): Correct sh_type
+       to SHT_NOBITS earlier.  Base actions in rest of function on sh_type
+       and sh_flags instead of bfd section flags.  Delete voff and code
+       keeping nobits segments aligned.
+
 2007-05-25  Eric Christopher  <echristo@apple.com>
 
        * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame):
index f39fdfa..25266ea 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4282,7 +4282,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
   struct elf_segment_map *m;
   Elf_Internal_Phdr *phdrs;
   Elf_Internal_Phdr *p;
-  file_ptr off, voff;
+  file_ptr off;
   bfd_size_type maxpagesize;
   unsigned int alloc;
   unsigned int i, j;
@@ -4344,10 +4344,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
         number of sections with contents contributing to both p_filesz
         and p_memsz, followed by a number of sections with no contents
         that just contribute to p_memsz.  In this loop, OFF tracks next
-        available file offset for PT_LOAD and PT_NOTE segments.  VOFF is
-        an adjustment we use for segments that have no file contents
-        but need zero filled memory allocation.  */
-      voff = 0;
+        available file offset for PT_LOAD and PT_NOTE segments.  */
       p->p_type = m->p_type;
       p->p_flags = m->p_flags;
 
@@ -4410,31 +4407,34 @@ assign_file_positions_for_load_sections (bfd *abfd,
                align = maxpagesize;
            }
 
+         for (i = 0; i < m->count; i++)
+           if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+             /* If we aren't making room for this section, then
+                it must be SHT_NOBITS regardless of what we've
+                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);
-         off += adjust;
-         if (adjust != 0
-             && !m->includes_filehdr
-             && !m->includes_phdrs
-             && (ufile_ptr) off >= align)
+         if (adjust != 0)
            {
-             /* If the first section isn't loadable, the same holds for
-                any other sections.  Since the segment won't need file
-                space, we can make p_offset overlap some prior segment.
-                However, .tbss is special.  If a segment starts with
-                .tbss, we need to look at the next section to decide
-                whether the segment has any loadable sections.  */
+             /* 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 ((m->sections[i]->flags & SEC_LOAD) == 0
-                    && (m->sections[i]->flags & SEC_HAS_CONTENTS) == 0)
+             while (elf_section_type (m->sections[i]) == SHT_NOBITS)
                {
-                 if ((m->sections[i]->flags & SEC_THREAD_LOCAL) == 0
+                 /* 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)
                    {
-                     off -= adjust;
-                     voff = adjust - align;
+                     adjust = 0;
                      break;
                    }
                }
+             off += adjust;
            }
        }
       /* Make sure the .dynamic section is the first section in the
@@ -4505,7 +4505,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
          || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
        {
          if (! m->includes_filehdr && ! m->includes_phdrs)
-           p->p_offset = off + voff;
+           p->p_offset = off;
          else
            {
              file_ptr adjust;
@@ -4524,12 +4524,11 @@ assign_file_positions_for_load_sections (bfd *abfd,
       for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
        {
          asection *sec;
-         flagword flags;
          bfd_size_type align;
          Elf_Internal_Shdr *this_hdr;
 
          sec = *secpp;
-         flags = sec->flags;
+         this_hdr = &elf_section_data (sec)->this_hdr;
          align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
 
          if (p->p_type == PT_LOAD
@@ -4537,9 +4536,9 @@ assign_file_positions_for_load_sections (bfd *abfd,
            {
              bfd_signed_vma adjust = sec->lma - (p->p_paddr + p->p_memsz);
 
-             if ((flags & SEC_LOAD) != 0
-                 || ((flags & SEC_ALLOC) != 0
-                     && ((flags & SEC_THREAD_LOCAL) == 0
+             if (this_hdr->sh_type != SHT_NOBITS
+                 || ((this_hdr->sh_flags & SHF_ALLOC) != 0
+                     && ((this_hdr->sh_flags & SHF_TLS) == 0
                          || p->p_type == PT_TLS)))
                {
                  if (adjust < 0)
@@ -4551,7 +4550,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
                    }
                  p->p_memsz += adjust;
 
-                 if ((flags & SEC_LOAD) != 0)
+                 if (this_hdr->sh_type != SHT_NOBITS)
                    {
                      off += adjust;
                      p->p_filesz += adjust;
@@ -4559,7 +4558,6 @@ assign_file_positions_for_load_sections (bfd *abfd,
                }
            }
 
-         this_hdr = &elf_section_data (sec)->this_hdr;
          if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
            {
              /* The section at i == 0 is the one that actually contains
@@ -4585,46 +4583,25 @@ assign_file_positions_for_load_sections (bfd *abfd,
            {
              if (p->p_type == PT_LOAD)
                {
-                 this_hdr->sh_offset = sec->filepos = off + voff;
-                 /* FIXME: The SEC_HAS_CONTENTS test here dates back to
-                    1997, and the exact reason for it isn't clear.  One
-                    plausible explanation is that it is to work around
-                    a problem we have with linker scripts using data
-                    statements in NOLOAD sections.  I don't think it
-                    makes a great deal of sense to have such a section
-                    assigned to a PT_LOAD segment, but apparently
-                    people do this.  The data statement results in a
-                    bfd_data_link_order being built, and these need
-                    section contents to write into.  Eventually, we get
-                    to _bfd_elf_write_object_contents which writes any
-                    section with contents to the output.  Make room
-                    here for the write, so that following segments are
-                    not trashed.  */
-                 if ((flags & SEC_LOAD) != 0
-                     || (flags & SEC_HAS_CONTENTS) != 0)
+                 this_hdr->sh_offset = sec->filepos = off;
+                 if (this_hdr->sh_type != SHT_NOBITS)
                    off += sec->size;
-                 else
-                   /* If we aren't making room for this section, then
-                      it must be SHT_NOBITS regardless of what we've
-                      set via struct bfd_elf_special_section.  */
-                   this_hdr->sh_type = SHT_NOBITS;
                }
 
-             if ((flags & SEC_LOAD) != 0)
+             if (this_hdr->sh_type != SHT_NOBITS)
                {
                  p->p_filesz += sec->size;
-                 /* SEC_LOAD without SEC_ALLOC is a weird combination
-                    used by note sections to signify that a PT_NOTE
-                    segment should be created.  These take file space
-                    but are not actually loaded into memory.  */
-                 if ((flags & SEC_ALLOC) != 0)
+                 /* A load section without SHF_ALLOC is something like
+                    a note section in a PT_NOTE segment.  These take
+                    file space but are not loaded into memory.  */
+                 if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
                    p->p_memsz += sec->size;
                }
 
              /* .tbss is special.  It doesn't contribute to p_memsz of
                 normal segments.  */
-             else if ((flags & SEC_ALLOC) != 0
-                      && ((flags & SEC_THREAD_LOCAL) == 0
+             else if ((this_hdr->sh_flags & SHF_ALLOC) != 0
+                      && ((this_hdr->sh_flags & SHF_TLS) == 0
                           || p->p_type == PT_TLS))
                p->p_memsz += sec->size;
 
@@ -4649,9 +4626,9 @@ assign_file_positions_for_load_sections (bfd *abfd,
          if (! m->p_flags_valid)
            {
              p->p_flags |= PF_R;
-             if ((flags & SEC_CODE) != 0)
+             if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0)
                p->p_flags |= PF_X;
-             if ((flags & SEC_READONLY) == 0)
+             if ((this_hdr->sh_flags & SHF_WRITE) != 0)
                p->p_flags |= PF_W;
            }
        }