bfd/
authorAlan Modra <amodra@gmail.com>
Wed, 22 Sep 2004 06:45:39 +0000 (06:45 +0000)
committerAlan Modra <amodra@gmail.com>
Wed, 22 Sep 2004 06:45:39 +0000 (06:45 +0000)
* elf.c (IS_LOADED): Define.
(assign_file_positions_for_segments): Don't round up file offset of
PT_LOAD segments containing no SEC_LOAD sections, instead round down.
Delete code handling link script adjustment of lma.  Do the adjust
in later code handling similar ajustments.  Remove dead code error
check.  Warn if section lma would require a negative offset
adjustment.  Tweak lma adjustment to use p_filesz rather than p_memsz.
Use p_vaddr + p_memsz inside section loop in place of voff.  Don't
update voff in section loop.  Change voff in segment loop to be an
adjustment on top of "off".  Set sec->filepos and update "off" later.
Test for loadable sections consistently using IS_LOADED.  Similarly,
test for alloc-only sections other than .tbss consistently.
Don't bother checking SEC_ALLOC in PT_LOAD segments.  Remove FIXME.
Tidy PT_NOTE handling.  Use %B and %A in error messages.
(assign_file_positions_except_relocs): Use %B in error message.

ld/testsuite/
* ld-scripts/overlay-size.d: Don't check .mbss lma.
* ld-sh/sh64/mix1.xd: Update for changed .bss file offset.
* ld-sh/sh64/shdl32.xd: Likewise.
* ld-sh/sh64/shdl64.xd: Likewise.

bfd/ChangeLog
bfd/elf.c
ld/testsuite/ChangeLog
ld/testsuite/ld-scripts/overlay-size.d
ld/testsuite/ld-sh/sh64/mix1.xd
ld/testsuite/ld-sh/sh64/shdl32.xd
ld/testsuite/ld-sh/sh64/shdl64.xd

index 27813dcff5f8d5fb9ce126c09a1551b8fcfe6fd1..e3c341b8f75386b1e84b3ed583fee7020169aaee 100644 (file)
@@ -1,3 +1,21 @@
+2004-09-22  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf.c (IS_LOADED): Define.
+       (assign_file_positions_for_segments): Don't round up file offset of
+       PT_LOAD segments containing no SEC_LOAD sections, instead round down.
+       Delete code handling link script adjustment of lma.  Do the adjust
+       in later code handling similar ajustments.  Remove dead code error
+       check.  Warn if section lma would require a negative offset
+       adjustment.  Tweak lma adjustment to use p_filesz rather than p_memsz.
+       Use p_vaddr + p_memsz inside section loop in place of voff.  Don't
+       update voff in section loop.  Change voff in segment loop to be an
+       adjustment on top of "off".  Set sec->filepos and update "off" later.
+       Test for loadable sections consistently using IS_LOADED.  Similarly,
+       test for alloc-only sections other than .tbss consistently.  
+       Don't bother checking SEC_ALLOC in PT_LOAD segments.  Remove FIXME.
+       Tidy PT_NOTE handling.  Use %B and %A in error messages.
+       (assign_file_positions_except_relocs): Use %B in error message.
+
 2004-09-17  H.J. Lu  <hongjiu.lu@intel.com>
 
        * Makefile.am (AUTOMAKE_OPTIONS): Require 1.9.
index c57da590e25e372938309f4b3885f067e1c2948a..2b73cde4ebc04e7f867a8d31326da8fb5799c231 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -3787,6 +3787,12 @@ vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
   return ((vma - off) % maxpagesize);
 }
 
+/* We check SEC_HAS_CONTENTS here because if NOLOAD is used in a linker
+   script we may have a section with SEC_LOAD clear but which is
+   supposed to have contents.  */
+#define IS_LOADED(FLAGS) \
+  (((FLAGS) & SEC_LOAD) != 0 || ((FLAGS) & SEC_HAS_CONTENTS) != 0)
+
 /* 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, and writes out the program headers.  */
@@ -3866,8 +3872,8 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
   if (alloc != 0 && count > alloc)
     {
       ((*_bfd_error_handler)
-       (_("%s: Not enough room for program headers (allocated %u, need %u)"),
-       bfd_get_filename (abfd), alloc, count));
+       (_("%B: Not enough room for program headers (allocated %u, need %u)"),
+       abfd, alloc, count));
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
     }
@@ -3906,32 +3912,63 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
        qsort (m->sections, (size_t) m->count, sizeof (asection *),
               elf_sort_sections);
 
+      /* An ELF segment (described by Elf_Internal_Phdr) may contain a
+        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;
       p->p_type = m->p_type;
       p->p_flags = m->p_flags;
 
       if (p->p_type == PT_LOAD
-         && m->count > 0
-         && (m->sections[0]->flags & SEC_ALLOC) != 0)
+         && m->count > 0)
        {
+         bfd_size_type align;
+         bfd_vma adjust;
+
          if ((abfd->flags & D_PAGED) != 0)
-           off += vma_page_aligned_bias (m->sections[0]->vma, off,
-                                         bed->maxpagesize);
+           align = bed->maxpagesize;
          else
            {
-             bfd_size_type align;
-
-             align = 0;
+             unsigned int align_power = 0;
              for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
                {
-                 bfd_size_type secalign;
+                 unsigned int secalign;
 
                  secalign = bfd_get_section_alignment (abfd, *secpp);
-                 if (secalign > align)
-                   align = secalign;
+                 if (secalign > align_power)
+                   align_power = secalign;
                }
+             align = (bfd_size_type) 1 << align_power;
+           }
 
-             off += vma_page_aligned_bias (m->sections[0]->vma, off,
-                                           1 << align);
+         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 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.  */
+             i = 0;
+             while (!IS_LOADED (m->sections[i]->flags))
+               {
+                 if ((m->sections[i]->flags & SEC_THREAD_LOCAL) == 0
+                     || ++i >= m->count)
+                   {
+                     off -= adjust;
+                     voff = adjust - align;
+                     break;
+                   }
+               }
            }
        }
       /* Make sure the .dynamic section is the first section in the
@@ -3941,8 +3978,8 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
               && strcmp (m->sections[0]->name, ".dynamic") != 0)
        {
          _bfd_error_handler
-           (_("%s: The first section in the PT_DYNAMIC segment is not the .dynamic section"),
-            bfd_get_filename (abfd));
+           (_("%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"),
+            abfd);
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
        }
@@ -3985,8 +4022,8 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
              if (p->p_vaddr < (bfd_vma) off)
                {
                  (*_bfd_error_handler)
-                   (_("%s: Not enough room for program headers, try linking with -N"),
-                    bfd_get_filename (abfd));
+                   (_("%B: Not enough room for program headers, try linking with -N"),
+                    abfd);
                  bfd_set_error (bfd_error_bad_value);
                  return FALSE;
                }
@@ -4044,7 +4081,7 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
          || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
        {
          if (! m->includes_filehdr && ! m->includes_phdrs)
-           p->p_offset = off;
+           p->p_offset = off + voff;
          else
            {
              file_ptr adjust;
@@ -4055,8 +4092,6 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
            }
        }
 
-      voff = off;
-
       for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
        {
          asection *sec;
@@ -4067,117 +4102,82 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
          flags = sec->flags;
          align = 1 << bfd_get_section_alignment (abfd, sec);
 
-         /* The section may have artificial alignment forced by a
-            link script.  Notice this case by the gap between the
-            cumulative phdr lma and the section's lma.  */
-         if (p->p_paddr + p->p_memsz < sec->lma)
-           {
-             bfd_vma adjust = sec->lma - (p->p_paddr + p->p_memsz);
-
-             p->p_memsz += adjust;
-             if (p->p_type == PT_LOAD
-                 || (p->p_type == PT_NOTE
-                     && bfd_get_format (abfd) == bfd_core))
-               {
-                 off += adjust;
-                 voff += adjust;
-               }
-             if ((flags & SEC_LOAD) != 0
-                 || (flags & SEC_THREAD_LOCAL) != 0)
-               p->p_filesz += adjust;
-           }
-
-         if (p->p_type == PT_LOAD)
+         if (p->p_type == PT_LOAD
+             || p->p_type == PT_TLS)
            {
              bfd_signed_vma adjust;
 
-             if ((flags & SEC_LOAD) != 0)
+             if (IS_LOADED (flags))
                {
-                 adjust = sec->lma - (p->p_paddr + p->p_memsz);
+                 adjust = sec->lma - (p->p_paddr + p->p_filesz);
                  if (adjust < 0)
-                   adjust = 0;
+                   {
+                     (*_bfd_error_handler)
+                       (_("%B: section %A lma 0x%lx overlaps previous sections"),
+                        abfd, sec, (unsigned long) sec->lma);
+                     adjust = 0;
+                   }
+                 off += adjust;
+                 p->p_filesz += adjust;
+                 p->p_memsz += adjust;
                }
-             else if ((flags & SEC_ALLOC) != 0)
+             /* .tbss is special.  It doesn't contribute to p_memsz of
+                normal segments.  */
+             else if ((flags & SEC_THREAD_LOCAL) == 0
+                      || p->p_type == PT_TLS)
                {
                  /* The section VMA must equal the file position
-                    modulo the page size.  FIXME: I'm not sure if
-                    this adjustment is really necessary.  We used to
-                    not have the SEC_LOAD case just above, and then
-                    this was necessary, but now I'm not sure.  */
+                    modulo the page size.  */
+                 bfd_size_type page = align;
                  if ((abfd->flags & D_PAGED) != 0)
-                   adjust = vma_page_aligned_bias (sec->vma, voff,
-                                                   bed->maxpagesize);
-                 else
-                   adjust = vma_page_aligned_bias (sec->vma, voff,
-                                                   align);
-               }
-             else
-               adjust = 0;
-
-             if (adjust != 0)
-               {
-                 if (i == 0)
-                   {
-                     (* _bfd_error_handler) (_("\
-Error: First section in segment (%s) starts at 0x%x whereas the segment starts at 0x%x"),
-                                             bfd_section_name (abfd, sec),
-                                             sec->lma,
-                                             p->p_paddr);
-                     return FALSE;
-                   }
+                   page = bed->maxpagesize;
+                 adjust = vma_page_aligned_bias (sec->vma,
+                                                 p->p_vaddr + p->p_memsz,
+                                                 page);
                  p->p_memsz += adjust;
-                 off += adjust;
-                 voff += adjust;
-                 if ((flags & SEC_LOAD) != 0)
-                   p->p_filesz += adjust;
                }
-
-             sec->filepos = off;
-
-             /* We check SEC_HAS_CONTENTS here because if NOLOAD is
-                 used in a linker script we may have a section with
-                 SEC_LOAD clear but which is supposed to have
-                 contents.  */
-             if ((flags & SEC_LOAD) != 0
-                 || (flags & SEC_HAS_CONTENTS) != 0)
-               off += sec->size;
-
-             if ((flags & SEC_ALLOC) != 0
-                 && ((flags & SEC_LOAD) != 0
-                     || (flags & SEC_THREAD_LOCAL) == 0))
-               voff += sec->size;
            }
 
          if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
            {
-             /* The actual "note" segment has i == 0.
-                This is the one that actually contains everything.  */
+             /* The section at i == 0 is the one that actually contains
+                everything.  */
              if (i == 0)
                {
                  sec->filepos = off;
-                 p->p_filesz = sec->size;
                  off += sec->size;
-                 voff = off;
+                 p->p_filesz = sec->size;
+                 p->p_memsz = 0;
+                 p->p_align = 1;
                }
              else
                {
-                 /* Fake sections -- don't need to be written.  */
+                 /* The rest are fake sections that shouldn't be written.  */
                  sec->filepos = 0;
                  sec->size = 0;
-                 flags = sec->flags = 0;
+                 sec->flags = 0;
+                 continue;
                }
-             p->p_memsz = 0;
-             p->p_align = 1;
            }
          else
            {
-             if ((sec->flags & SEC_LOAD) != 0
-                 || (sec->flags & SEC_THREAD_LOCAL) == 0
-                 || p->p_type == PT_TLS)
-             p->p_memsz += sec->size;
+             if (p->p_type == PT_LOAD)
+               {
+                 sec->filepos = off;
+                 if (IS_LOADED (flags))
+                   off += sec->size;
+               }
 
-             if ((flags & SEC_LOAD) != 0)
-               p->p_filesz += sec->size;
+             if (IS_LOADED (flags))
+               {
+                 p->p_filesz += sec->size;
+                 p->p_memsz += sec->size;
+               }
+             /* .tbss is special.  It doesn't contribute to p_memsz of
+                normal segments.  */
+             else if ((flags & SEC_THREAD_LOCAL) == 0
+                      || p->p_type == PT_TLS)
+               p->p_memsz += sec->size;
 
              if (p->p_type == PT_TLS
                  && sec->size == 0
@@ -4493,8 +4493,8 @@ assign_file_positions_except_relocs (bfd *abfd,
          else if ((hdr->sh_flags & SHF_ALLOC) != 0)
            {
              ((*_bfd_error_handler)
-              (_("%s: warning: allocated section `%s' not in segment"),
-               bfd_get_filename (abfd),
+              (_("%B: warning: allocated section `%s' not in segment"),
+               abfd,
                (hdr->bfd_section == NULL
                 ? "*unknown*"
                 : hdr->bfd_section->name)));
index bc25d1c0a9ce8ebe1eaf57d0ef2255d0fccb9b7b..428bc228c02a59a74d0436dacfc6d50b968b08e3 100644 (file)
@@ -1,3 +1,10 @@
+2004-09-22  Alan Modra  <amodra@bigpond.net.au>
+
+       * ld-scripts/overlay-size.d: Don't check .mbss lma.
+       * ld-sh/sh64/mix1.xd: Update for changed .bss file offset.
+       * ld-sh/sh64/shdl32.xd: Likewise.
+       * ld-sh/sh64/shdl64.xd: Likewise.
+
 2004-09-17  Paul Brook  <paul@codesourcery.com>
 
        * ld-arm/arm-target1-{abs,rel}.d}: New files.
index cf1f5e855137aa179cb1a2491142bed0f8be03af..f54f56dfe71f4ac9277b6e1263c9162e6b70e381 100644 (file)
@@ -13,7 +13,7 @@
 #...
   3 \.mtext +0+020 +0+10000 +0+30000 .*
 #...
-  4 \.mbss +0+230 +0+20030 +0+20060 .*
+  4 \.mbss +0+230 +0+20030 .*
 #...
   5 \.text1 +0+080 +0+10020 +0+30020 .*
 #...
index a5c732b10d415e45ecc4cb3a3c13a1b7b8a4426e..005e161a647b1404fef195853fc0db0a4ced5331 100644 (file)
@@ -24,7 +24,7 @@ Idx Name          Size      VMA       LMA       File off  Algn
                   CONTENTS, ALLOC, LOAD, DATA
   4 \.sbss         00000000  0+10d8  0+10d8  00000184  2\*\*0
                   CONTENTS
-  5 \.bss          00000000  0+10d8  0+10d8  00000158  2\*\*0
+  5 \.bss          00000000  0+10d8  0+10d8  00000154  2\*\*0
                   ALLOC
   6 \.stack        00000004  0+80000  0+80000  00000180  2\*\*0
                   CONTENTS, ALLOC, LOAD, DATA
index 663cfc8367e11289613f564924c740d7b47099ad..0e46444c2d50c02c36c10e60be6790492655fe1e 100644 (file)
@@ -26,7 +26,7 @@ Idx Name          Size      VMA       LMA       File off  Algn
                   CONTENTS, ALLOC, LOAD, DATA
   5 \.sbss         0+  0+1560  0+1560  0+604  2\*\*0
                   CONTENTS
-  6 \.bss          0+  0+1560  0+1560  0+5e0  2\*\*0
+  6 \.bss          0+  0+1560  0+1560  0+5dc  2\*\*0
                   ALLOC
   7 \.stack        0+4  0+80000  0+80000  0+600  2\*\*0
                   CONTENTS, ALLOC, LOAD, DATA
index 26ae839abbbe5aa20b82d694e83550655e4a26d6..48826c3edc533f69e4b48492f19c578009a85f43 100644 (file)
@@ -26,7 +26,7 @@ Idx Name          Size      VMA               LMA               File off  Algn
                   CONTENTS, ALLOC, LOAD, DATA
   5 \.sbss         0+  0+1560  0+1560  0+604  2\*\*0
                   CONTENTS
-  6 \.bss          0+  0+1560  0+1560  0+5e0  2\*\*0
+  6 \.bss          0+  0+1560  0+1560  0+5dc  2\*\*0
                   ALLOC
   7 \.stack        0+4  0+80000  0+80000  0+600  2\*\*0
                   CONTENTS, ALLOC, LOAD, DATA