elf: Strip zero-sized dynamic sections
[deliverable/binutils-gdb.git] / bfd / elf.c
index f5354d2c7a11cf62dd2679aaec14cf3d2804f2a1..f3364eeddf2a5db3b8e209e82c76278af574c83b 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1887,9 +1887,9 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
    and return symbol version for symbol version itself.   */
 
 const char *
-_bfd_elf_get_symbol_version_name (bfd *abfd, asymbol *symbol,
-                                 bfd_boolean base_p,
-                                 bfd_boolean *hidden)
+_bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol,
+                                   bfd_boolean base_p,
+                                   bfd_boolean *hidden)
 {
   const char *version_string = NULL;
   if (elf_dynversym (abfd) != 0
@@ -1911,8 +1911,12 @@ _bfd_elf_get_symbol_version_name (bfd *abfd, asymbol *symbol,
        {
          const char *nodename
            = elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
-         version_string = ((base_p || strcmp (symbol->name, nodename))
-                           ? nodename : "");
+         version_string = "";
+         if (base_p
+             || nodename == NULL
+             || symbol->name == NULL
+             || strcmp (symbol->name, nodename) != 0)
+           version_string = nodename;
        }
       else
        {
@@ -1939,15 +1943,6 @@ _bfd_elf_get_symbol_version_name (bfd *abfd, asymbol *symbol,
   return version_string;
 }
 
-/* Get version string.  */
-
-const char *
-_bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol,
-                                   bfd_boolean *hidden)
-{
-  return _bfd_elf_get_symbol_version_name (abfd, symbol, TRUE, hidden);
-}
-
 /* Display ELF-specific fields of a symbol.  */
 
 void
@@ -2003,6 +1998,7 @@ bfd_elf_print_symbol (bfd *abfd,
        /* If we have version information, print it.  */
        version_string = _bfd_elf_get_symbol_version_string (abfd,
                                                             symbol,
+                                                            TRUE,
                                                             &hidden);
        if (version_string)
          {
@@ -4006,9 +4002,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
                  elf_section_data (s)->this_hdr.sh_link = d->this_idx;
 
                  /* This is a .stab section.  */
-                 if (elf_section_data (s)->this_hdr.sh_entsize == 0)
-                   elf_section_data (s)->this_hdr.sh_entsize
-                     = 4 + 2 * bfd_get_arch_size (abfd) / 8;
+                 elf_section_data (s)->this_hdr.sh_entsize = 12;
                }
            }
          break;
@@ -5841,10 +5835,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.
@@ -5854,10 +5849,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)
@@ -7921,19 +7931,34 @@ _bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded)
                elf_section_flags (s->output_section) &= ~SHF_GROUP;
                elf_group_name (s->output_section) = NULL;
              }
-           /* Conversely, if the member section is not being output
-              but the SHT_GROUP section is, then adjust its size.  */
-           else if (s->output_section == discarded
-                    && isec->output_section != discarded)
+           else
              {
                struct bfd_elf_section_data *elf_sec = elf_section_data (s);
-               removed += 4;
-               if (elf_sec->rel.hdr != NULL
-                   && (elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0)
-                 removed += 4;
-               if (elf_sec->rela.hdr != NULL
-                   && (elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0)
-                 removed += 4;
+               if (s->output_section == discarded
+                   && isec->output_section != discarded)
+                 {
+                   /* Conversely, if the member section is not being
+                      output but the SHT_GROUP section is, then adjust
+                      its size.  */
+                   removed += 4;
+                   if (elf_sec->rel.hdr != NULL
+                       && (elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0)
+                     removed += 4;
+                   if (elf_sec->rela.hdr != NULL
+                       && (elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0)
+                     removed += 4;
+                 }
+               else
+                 {
+                   /* Also adjust for zero-sized relocation member
+                      section.  */
+                   if (elf_sec->rel.hdr != NULL
+                       && elf_sec->rel.hdr->sh_size == 0)
+                     removed += 4;
+                   if (elf_sec->rela.hdr != NULL
+                       && elf_sec->rela.hdr->sh_size == 0)
+                     removed += 4;
+                 }
              }
            s = elf_next_in_group (s);
            if (s == first)
This page took 0.040909 seconds and 4 git commands to generate.