PR25662, invalid sh_offset for first section in segment with phdrs
authorAlan Modra <amodra@gmail.com>
Tue, 24 Mar 2020 00:12:45 +0000 (10:42 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 25 Mar 2020 04:21:41 +0000 (14:51 +1030)
PR 25662
* elf.c (assign_file_positions_for_load_sections): Adjust offset
for SHT_NOBITS section if first in segment.

bfd/ChangeLog
bfd/elf.c

index f273ea54e9b25d06965e34f9ed3d2bb22c1cd0ca..b4160c943a5b1a1d836edf7146b7bda1b04f9c38 100644 (file)
@@ -1,3 +1,9 @@
+2020-03-25  Alan Modra  <amodra@gmail.com>
+
+       PR 25662
+       * elf.c (assign_file_positions_for_load_sections): Adjust offset
+       for SHT_NOBITS section if first in segment.
+
 2020-03-24  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR binutils/25708
index 2512b6543b1b19d3e141da8de041dc7d104babce..86dadea05caff48339c36872f1bff867f711fd17 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -5833,10 +5833,11 @@ assign_file_positions_for_load_sections (bfd *abfd,
                }
              p->p_memsz += adjust;
 
-             if (this_hdr->sh_type != SHT_NOBITS)
+             if (p->p_type == PT_LOAD)
                {
-                 if (p->p_type == PT_LOAD)
+                 if (this_hdr->sh_type != SHT_NOBITS)
                    {
+                     off_adjust = 0;
                      if (p->p_filesz + adjust < p->p_memsz)
                        {
                          /* We have a PROGBITS section following NOBITS ones.
@@ -5846,10 +5847,25 @@ assign_file_positions_for_load_sections (bfd *abfd,
                          if (!write_zeros (abfd, off, adjust))
                            return FALSE;
                        }
+                   }
+                 /* We only adjust sh_offset in SHT_NOBITS sections
+                    as would seem proper for their address when the
+                    section is first in the segment.  sh_offset
+                    doesn't really have any significance for
+                    SHT_NOBITS anyway, apart from a notional position
+                    relative to other sections.  Historically we
+                    didn't bother with adjusting sh_offset and some
+                    programs depend on it not being adjusted.  See
+                    pr12921 and pr25662.  */
+                 if (this_hdr->sh_type != SHT_NOBITS || i == 0)
+                   {
                      off += adjust;
+                     if (this_hdr->sh_type == SHT_NOBITS)
+                       off_adjust += adjust;
                    }
-                 p->p_filesz += adjust;
                }
+             if (this_hdr->sh_type != SHT_NOBITS)
+               p->p_filesz += adjust;
            }
 
          if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)