PR 12763
authorAlan Modra <amodra@gmail.com>
Fri, 20 May 2011 15:32:24 +0000 (15:32 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 20 May 2011 15:32:24 +0000 (15:32 +0000)
* elf.c (_bfd_elf_make_section_from_shdr): Set up TLS section LMAs
from PT_TLS header.
(_bfd_elf_map_sections_to_segments): Don't create a final PT_LOAD
segment if just for .tbss.
(assign_file_positions_for_load_sections): Don't report "can't
allocate in segment" errors for .tbss.
(assign_file_positions_for_non_load_sections): Don't set p_filesz
from SHT_NOBITS section filepos.

bfd/ChangeLog
bfd/elf.c

index 7cdd2156f0987d97693b2d0d4e0d045626a7e3d2..4517a4f46e6587ef839a10ebee69c49b06ff356f 100644 (file)
@@ -1,3 +1,15 @@
+2011-05-21  Alan Modra  <amodra@gmail.com>
+
+       PR 12763
+       * elf.c (_bfd_elf_make_section_from_shdr): Set up TLS section LMAs
+       from PT_TLS header.
+       (_bfd_elf_map_sections_to_segments): Don't create a final PT_LOAD
+       segment if just for .tbss.
+       (assign_file_positions_for_load_sections): Don't report "can't
+       allocate in segment" errors for .tbss.
+       (assign_file_positions_for_non_load_sections): Don't set p_filesz
+       from SHT_NOBITS section filepos.
+
 2011-05-20  Bernd Schmidt  <bernds@codesourcery.com>
 
        * elf32-tic6x.c (elf32_tic6x_howto_table): Add entries for
index 33a3a7d8cfd6ee4937bf34f76ef2180fc414d6a5..ffc9c8e2d538cb8403ef323aafa60bffdd131792 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -976,7 +976,9 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
       phdr = elf_tdata (abfd)->phdr;
       for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
        {
-         if (phdr->p_type == PT_LOAD
+         if (((phdr->p_type == PT_LOAD
+               && (hdr->sh_flags & SHF_TLS) == 0)
+              || phdr->p_type == PT_TLS)
              && ELF_SECTION_IN_SEGMENT (hdr, phdr))
            {
              if ((flags & SEC_LOAD) == 0)
@@ -3987,8 +3989,12 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
          phdr_in_segment = FALSE;
        }
 
-      /* Create a final PT_LOAD program segment.  */
-      if (last_hdr != NULL)
+      /* Create a final PT_LOAD program segment, but not if it's just
+        for .tbss.  */
+      if (last_hdr != NULL
+         && (i - phdr_index != 1
+             || ((last_hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
+                 != SEC_THREAD_LOCAL)))
        {
          m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
          if (m == NULL)
@@ -4748,7 +4754,8 @@ assign_file_positions_for_load_sections (bfd *abfd,
 
              sec = m->sections[i];
              this_hdr = &(elf_section_data(sec)->this_hdr);
-             if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0))
+             if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0)
+                 && !ELF_TBSS_SPECIAL (this_hdr, p))
                {
                  (*_bfd_error_handler)
                    (_("%B: section `%A' can't be allocated in segment %d"),
@@ -4919,17 +4926,21 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
              && (p->p_type != PT_NOTE
                  || bfd_get_format (abfd) != bfd_core))
            {
-             Elf_Internal_Shdr *hdr;
-             asection *sect;
-
              BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
 
-             sect = m->sections[m->count - 1];
-             hdr = &elf_section_data (sect)->this_hdr;
-             p->p_filesz = sect->filepos - m->sections[0]->filepos;
-             if (hdr->sh_type != SHT_NOBITS)
-               p->p_filesz += hdr->sh_size;
+             p->p_filesz = 0;
              p->p_offset = m->sections[0]->filepos;
+             for (i = m->count; i-- != 0;)
+               {
+                 asection *sect = m->sections[i];
+                 Elf_Internal_Shdr *hdr = &elf_section_data (sect)->this_hdr;
+                 if (hdr->sh_type != SHT_NOBITS)
+                   {
+                     p->p_filesz = (sect->filepos - m->sections[0]->filepos
+                                    + hdr->sh_size);
+                     break;
+                   }
+               }
            }
        }
       else if (m->includes_filehdr)