2006-10-26 H.J. Lu <hongjiu.lu@intel.com>
[deliverable/binutils-gdb.git] / bfd / elf.c
index b90061301cf4b88a0704fc1ba633b04488393883..24ca6df7c9e3cfef7883e933c37a30a49f8b0e86 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -400,7 +400,15 @@ bfd_elf_get_elf_syms (bfd *ibfd,
   for (esym = extsym_buf, isym = intsym_buf, shndx = extshndx_buf;
        isym < isymend;
        esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
-    (*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym);
+    if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
+      {
+       symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
+       (*_bfd_error_handler) (_("%B symbol number %lu references "
+                                "nonexistent SHT_SYMTAB_SHNDX section"),
+                              ibfd, (unsigned long) symoffset);
+       intsym_buf = NULL;
+       goto out;
+      }
 
  out:
   if (alloc_ext != NULL)
@@ -816,22 +824,22 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
          int len;
        } debug_sections [] =
        {
-         { "debug",             5  },  /* 'd' */
+         { STRING_COMMA_LEN ("debug") },       /* 'd' */
          { NULL,                0  },  /* 'e' */
          { NULL,                0  },  /* 'f' */
-         { "gnu.linkonce.wi.", 17 },   /* 'g' */
+         { STRING_COMMA_LEN ("gnu.linkonce.wi.") },    /* 'g' */
          { NULL,                0  },  /* 'h' */
          { NULL,                0  },  /* 'i' */
          { NULL,                0  },  /* 'j' */
          { NULL,                0  },  /* 'k' */
-         { "line",              4  },  /* 'l' */
+         { STRING_COMMA_LEN ("line") },        /* 'l' */
          { NULL,                0  },  /* 'm' */
          { NULL,                0  },  /* 'n' */
          { NULL,                0  },  /* 'o' */
          { NULL,                0  },  /* 'p' */
          { NULL,                0  },  /* 'q' */
          { NULL,                0  },  /* 'r' */
-         { "stab",              4  }   /* 's' */
+         { STRING_COMMA_LEN ("stab") } /* 's' */
        };
       
       if (name [0] == '.')
@@ -852,7 +860,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
      The symbols will be defined as weak, so that multiple definitions
      are permitted.  The GNU linker extension is to actually discard
      all but one of the sections.  */
-  if (strncmp (name, ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) == 0
+  if (CONST_STRNEQ (name, ".gnu.linkonce")
       && elf_next_in_group (newsect) == NULL)
     flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
 
@@ -1660,7 +1668,7 @@ bfd_elf_get_dyn_lib_class (bfd *abfd)
 }
 
 void
-bfd_elf_set_dyn_lib_class (bfd *abfd, int lib_class)
+bfd_elf_set_dyn_lib_class (bfd *abfd, enum dynamic_lib_link_class lib_class)
 {
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
       && bfd_get_format (abfd) == bfd_object)
@@ -2118,13 +2126,11 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
        abfd->flags |= HAS_RELOC;
        return TRUE;
       }
-      break;
 
     case SHT_GNU_verdef:
       elf_dynverdef (abfd) = shindex;
       elf_tdata (abfd)->dynverdef_hdr = *hdr;
       return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
-      break;
 
     case SHT_GNU_versym:
       if (hdr->sh_entsize != sizeof (Elf_External_Versym))
@@ -2281,109 +2287,111 @@ bfd_section_from_elf_index (bfd *abfd, unsigned int index)
 
 static const struct bfd_elf_special_section special_sections_b[] =
 {
-  { ".bss",            4, -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".bss"), -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
+  { NULL,                   0,  0, 0,            0 }
 };
 
 static const struct bfd_elf_special_section special_sections_c[] =
 {
-  { ".comment",        8,  0, SHT_PROGBITS, 0 },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".comment"), 0, SHT_PROGBITS, 0 },
+  { NULL,                       0, 0, 0,            0 }
 };
 
 static const struct bfd_elf_special_section special_sections_d[] =
 {
-  { ".data",           5, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
-  { ".data1",          6,  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
-  { ".debug",          6,  0, SHT_PROGBITS, 0 },
-  { ".debug_line",    11,  0, SHT_PROGBITS, 0 },
-  { ".debug_info",    11,  0, SHT_PROGBITS, 0 },
-  { ".debug_abbrev",  13,  0, SHT_PROGBITS, 0 },
-  { ".debug_aranges", 14,  0, SHT_PROGBITS, 0 },
-  { ".dynamic",        8,  0, SHT_DYNAMIC,  SHF_ALLOC },
-  { ".dynstr",         7,  0, SHT_STRTAB,   SHF_ALLOC },
-  { ".dynsym",         7,  0, SHT_DYNSYM,   SHF_ALLOC },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".data"),         -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".data1"),         0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".debug"),         0, SHT_PROGBITS, 0 },
+  { STRING_COMMA_LEN (".debug_line"),    0, SHT_PROGBITS, 0 },
+  { STRING_COMMA_LEN (".debug_info"),    0, SHT_PROGBITS, 0 },
+  { STRING_COMMA_LEN (".debug_abbrev"),  0, SHT_PROGBITS, 0 },
+  { STRING_COMMA_LEN (".debug_aranges"), 0, SHT_PROGBITS, 0 },
+  { STRING_COMMA_LEN (".dynamic"),       0, SHT_DYNAMIC,  SHF_ALLOC },
+  { STRING_COMMA_LEN (".dynstr"),        0, SHT_STRTAB,   SHF_ALLOC },
+  { STRING_COMMA_LEN (".dynsym"),        0, SHT_DYNSYM,   SHF_ALLOC },
+  { NULL,                      0,        0, 0,            0 }
 };
 
 static const struct bfd_elf_special_section special_sections_f[] =
 {
-  { ".fini",           5,  0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
-  { ".fini_array",    11,  0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".fini"),       0, SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR },
+  { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
+  { NULL,                          0, 0, 0,              0 }
 };
 
 static const struct bfd_elf_special_section special_sections_g[] =
 {
-  { ".gnu.linkonce.b",15, -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
-  { ".got",            4,  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
-  { ".gnu.version",   12,  0, SHT_GNU_versym, 0 },
-  { ".gnu.version_d", 14,  0, SHT_GNU_verdef, 0 },
-  { ".gnu.version_r", 14,  0, SHT_GNU_verneed, 0 },
-  { ".gnu.liblist",   12,  0, SHT_GNU_LIBLIST, SHF_ALLOC },
-  { ".gnu.conflict",  13,  0, SHT_RELA,     SHF_ALLOC },
-  { ".gnu.hash",       9,  0, SHT_GNU_HASH, SHF_ALLOC },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".got"),             0, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".gnu.version"),     0, SHT_GNU_versym,  0 },
+  { STRING_COMMA_LEN (".gnu.version_d"),   0, SHT_GNU_verdef,  0 },
+  { STRING_COMMA_LEN (".gnu.version_r"),   0, SHT_GNU_verneed, 0 },
+  { STRING_COMMA_LEN (".gnu.liblist"),     0, SHT_GNU_LIBLIST, SHF_ALLOC },
+  { STRING_COMMA_LEN (".gnu.conflict"),    0, SHT_RELA,        SHF_ALLOC },
+  { STRING_COMMA_LEN (".gnu.hash"),        0, SHT_GNU_HASH,    SHF_ALLOC },
+  { NULL,                        0,        0, 0,               0 }
 };
 
 static const struct bfd_elf_special_section special_sections_h[] =
 {
-  { ".hash",           5,  0, SHT_HASH,     SHF_ALLOC },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".hash"), 0, SHT_HASH,     SHF_ALLOC },
+  { NULL,                    0, 0, 0,            0 }
 };
 
 static const struct bfd_elf_special_section special_sections_i[] =
 {
-  { ".init",           5,  0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
-  { ".init_array",    11,  0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
-  { ".interp",         7,  0, SHT_PROGBITS, 0 },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".init"),       0, SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR },
+  { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".interp"),     0, SHT_PROGBITS,   0 },
+  { NULL,                      0,     0, 0,              0 }
 };
 
 static const struct bfd_elf_special_section special_sections_l[] =
 {
-  { ".line",           5,  0, SHT_PROGBITS, 0 },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".line"), 0, SHT_PROGBITS, 0 },
+  { NULL,                    0, 0, 0,            0 }
 };
 
 static const struct bfd_elf_special_section special_sections_n[] =
 {
-  { ".note.GNU-stack",15,  0, SHT_PROGBITS, 0 },
-  { ".note",           5, -1, SHT_NOTE,     0 },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 },
+  { STRING_COMMA_LEN (".note"),          -1, SHT_NOTE,     0 },
+  { NULL,                    0,           0, 0,            0 }
 };
 
 static const struct bfd_elf_special_section special_sections_p[] =
 {
-  { ".preinit_array", 14,  0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
-  { ".plt",            4,  0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".plt"),           0, SHT_PROGBITS,      SHF_ALLOC + SHF_EXECINSTR },
+  { NULL,                   0,           0, 0,                 0 }
 };
 
 static const struct bfd_elf_special_section special_sections_r[] =
 {
-  { ".rodata",         7, -2, SHT_PROGBITS, SHF_ALLOC },
-  { ".rodata1",        8,  0, SHT_PROGBITS, SHF_ALLOC },
-  { ".rela",           5, -1, SHT_RELA,     0 },
-  { ".rel",            4, -1, SHT_REL,      0 },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".rodata"), -2, SHT_PROGBITS, SHF_ALLOC },
+  { STRING_COMMA_LEN (".rodata1"), 0, SHT_PROGBITS, SHF_ALLOC },
+  { STRING_COMMA_LEN (".rela"),   -1, SHT_RELA,     0 },
+  { STRING_COMMA_LEN (".rel"),    -1, SHT_REL,      0 },
+  { NULL,                   0,     0, 0,            0 }
 };
 
 static const struct bfd_elf_special_section special_sections_s[] =
 {
-  { ".shstrtab",       9,  0, SHT_STRTAB,   0 },
-  { ".strtab",         7,  0, SHT_STRTAB,   0 },
-  { ".symtab",         7,  0, SHT_SYMTAB,   0 },
-  { ".stabstr",        5,  3, SHT_STRTAB,   0 },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".shstrtab"), 0, SHT_STRTAB, 0 },
+  { STRING_COMMA_LEN (".strtab"),   0, SHT_STRTAB, 0 },
+  { STRING_COMMA_LEN (".symtab"),   0, SHT_SYMTAB, 0 },
+  /* See struct bfd_elf_special_section declaration for the semantics of
+     this special case where .prefix_length != strlen (.prefix).  */
+  { ".stabstr",                        5,  3, SHT_STRTAB, 0 },
+  { NULL,                       0,  0, 0,          0 }
 };
 
 static const struct bfd_elf_special_section special_sections_t[] =
 {
-  { ".text",           5, -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
-  { ".tbss",           5, -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_TLS },
-  { ".tdata",          6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
-  { NULL,              0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".text"),  -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+  { STRING_COMMA_LEN (".tbss"),  -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_TLS },
+  { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
+  { NULL,                     0,  0, 0,            0 }
 };
 
 static const struct bfd_elf_special_section *special_sections[] =
@@ -3238,7 +3246,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
             string section.  We look for a section with the same name
             but without the trailing ``str'', and set its sh_link
             field to point to this section.  */
-         if (strncmp (sec->name, ".stab", sizeof ".stab" - 1) == 0
+         if (CONST_STRNEQ (sec->name, ".stab")
              && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0)
            {
              size_t len;
@@ -3622,6 +3630,13 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info)
     {
       /* We need a PT_DYNAMIC segment.  */
       ++segs;
+      
+      if (elf_tdata (abfd)->relro)
+       {
+         /* We need a PT_GNU_RELRO segment only when there is a
+            PT_DYNAMIC segment.  */
+         ++segs;
+       }
     }
 
   if (elf_tdata (abfd)->eh_frame_hdr)
@@ -3636,16 +3651,10 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info)
       ++segs;
     }
 
-  if (elf_tdata (abfd)->relro)
-    {
-      /* We need a PT_GNU_RELRO segment.  */
-      ++segs;
-    }
-
   for (s = abfd->sections; s != NULL; s = s->next)
     {
       if ((s->flags & SEC_LOAD) != 0
-         && strncmp (s->name, ".note", 5) == 0)
+         && CONST_STRNEQ (s->name, ".note"))
        {
          /* We need a PT_NOTE segment.  */
          ++segs;
@@ -3736,41 +3745,41 @@ _bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec)
 static bfd_boolean
 elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
 {
-  struct elf_segment_map *m;
+  struct elf_segment_map **m;
   const struct elf_backend_data *bed;
 
   /* The placement algorithm assumes that non allocated sections are
      not in PT_LOAD segments.  We ensure this here by removing such
      sections from the segment map.  We also remove excluded
-     sections.  */
-  for (m = elf_tdata (abfd)->segment_map;
-       m != NULL;
-       m = m->next)
+     sections.  Finally, any PT_LOAD segment without sections is
+     removed.  */
+  m = &elf_tdata (abfd)->segment_map;
+  while (*m)
     {
       unsigned int i, new_count;
 
-      new_count = 0;
-      for (i = 0; i < m->count; i ++)
+      for (new_count = 0, i = 0; i < (*m)->count; i++)
        {
-         if ((m->sections[i]->flags & SEC_EXCLUDE) == 0
-             && ((m->sections[i]->flags & SEC_ALLOC) != 0
-                 || m->p_type != PT_LOAD))
+         if (((*m)->sections[i]->flags & SEC_EXCLUDE) == 0
+             && (((*m)->sections[i]->flags & SEC_ALLOC) != 0
+                 || (*m)->p_type != PT_LOAD))
            {
-             if (i != new_count)
-               m->sections[new_count] = m->sections[i];
-
-             new_count ++;
+             (*m)->sections[new_count] = (*m)->sections[i];
+             new_count++;
            }
        }
+      (*m)->count = new_count;
 
-      if (new_count != m->count)
-       m->count = new_count;
+      if ((*m)->p_type == PT_LOAD && (*m)->count == 0)
+       *m = (*m)->next;
+      else
+       m = &(*m)->next;
     }
 
   bed = get_elf_backend_data (abfd);
   if (bed->elf_backend_modify_segment_map != NULL)
     {
-      if (! (*bed->elf_backend_modify_segment_map) (abfd, info))
+      if (!(*bed->elf_backend_modify_segment_map) (abfd, info))
        return FALSE;
     }
 
@@ -4027,7 +4036,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
       for (s = abfd->sections; s != NULL; s = s->next)
        {
          if ((s->flags & SEC_LOAD) != 0
-             && strncmp (s->name, ".note", 5) == 0)
+             && CONST_STRNEQ (s->name, ".note"))
            {
              amt = sizeof (struct elf_segment_map);
              m = bfd_zalloc (abfd, amt);
@@ -4110,8 +4119,10 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
          pm = &m->next;
        }
 
-      if (elf_tdata (abfd)->relro)
+      if (dynsec != NULL && elf_tdata (abfd)->relro)
        {
+         /* We make a PT_GNU_RELRO segment only when there is a
+            PT_DYNAMIC segment.  */
          amt = sizeof (struct elf_segment_map);
          m = bfd_zalloc (abfd, amt);
          if (m == NULL)
@@ -4379,7 +4390,8 @@ assign_file_positions_for_load_sections (bfd *abfd,
                 .tbss, we need to look at the next section to decide
                 whether the segment has any loadable sections.  */
              i = 0;
-             while ((m->sections[i]->flags & SEC_LOAD) == 0)
+             while ((m->sections[i]->flags & SEC_LOAD) == 0
+                    && (m->sections[i]->flags & SEC_HAS_CONTENTS) == 0)
                {
                  if ((m->sections[i]->flags & SEC_THREAD_LOCAL) == 0
                      || ++i >= m->count)
@@ -4548,7 +4560,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
            {
              if (p->p_type == PT_LOAD)
                {
-                 sec->filepos = off;
+                 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
@@ -4590,9 +4602,11 @@ assign_file_positions_for_load_sections (bfd *abfd,
                    p->p_memsz += o->offset + o->size;
                }
 
-             if (align > p->p_align
-                 && (p->p_type != PT_LOAD
-                     || (abfd->flags & D_PAGED) == 0))
+             if (p->p_type == PT_GNU_RELRO)
+               p->p_align = 1;
+             else if (align > p->p_align
+                      && (p->p_type != PT_LOAD
+                          || (abfd->flags & D_PAGED) == 0))
                p->p_align = align;
            }
 
@@ -4640,17 +4654,21 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
 
       hdr = *hdrpp;
       if (hdr->bfd_section != NULL
-         && hdr->bfd_section->filepos != 0)
+         && (hdr->bfd_section->filepos != 0
+             || (hdr->sh_type == SHT_NOBITS
+                 && hdr->contents == NULL)))
        hdr->sh_offset = hdr->bfd_section->filepos;
       else if ((hdr->sh_flags & SHF_ALLOC) != 0)
        {
-         ((*_bfd_error_handler)
-          (_("%B: warning: allocated section `%s' not in segment"),
-           abfd,
-           (hdr->bfd_section == NULL
-            ? "*unknown*"
-            : hdr->bfd_section->name)));
-         if ((abfd->flags & D_PAGED) != 0)
+         if (hdr->sh_size != 0)
+           ((*_bfd_error_handler)
+            (_("%B: warning: allocated section `%s' not in segment"),
+             abfd,
+             (hdr->bfd_section == NULL
+              ? "*unknown*"
+              : hdr->bfd_section->name)));
+         /* We don't need to page align empty sections.  */
+         if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
            off += vma_page_aligned_bias (hdr->sh_addr, off,
                                          bed->maxpagesize);
          else
@@ -5383,7 +5401,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
         all of the sections we have selected.  */
       amt = sizeof (struct elf_segment_map);
       amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
-      map = bfd_alloc (obfd, amt);
+      map = bfd_zalloc (obfd, amt);
       if (map == NULL)
        return FALSE;
 
@@ -5778,7 +5796,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
       amt = sizeof (struct elf_segment_map);
       if (section_count != 0)
        amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
-      map = bfd_alloc (obfd, amt);
+      map = bfd_zalloc (obfd, amt);
       if (map == NULL)
        return FALSE;
 
@@ -5932,9 +5950,17 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
      output BFD section flags have been set to something different.
      elf_fake_sections will set ELF section type based on BFD
      section flags.  */
-  if (osec->flags == isec->flags
-      || (osec->flags == 0 && elf_section_type (osec) == SHT_NULL))
-    elf_section_type (osec) = elf_section_type (isec);
+  if (osec->flags == isec->flags || !osec->flags)
+    {
+      BFD_ASSERT (osec->flags == isec->flags 
+                 || (!osec->flags
+                     && elf_section_type (osec) == SHT_NULL));
+      elf_section_type (osec) = elf_section_type (isec);
+    }
+
+  /* FIXME: Is this correct for all OS/PROC specific flags?  */
+  elf_section_flags (osec) |= (elf_section_flags (isec)
+                              & (SHF_MASKOS | SHF_MASKPROC));
 
   /* Set things up for objcopy and relocatable link.  The output
      SHT_GROUP section will have its elf_next_in_group pointing back
@@ -6004,6 +6030,8 @@ _bfd_elf_copy_private_section_data (bfd *ibfd,
 bfd_boolean
 _bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
 {
+  asection *isec;
+
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return TRUE;
@@ -6019,6 +6047,27 @@ _bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
        return FALSE;
     }
 
+  /* _bfd_elf_copy_private_section_data copied over the SHF_GROUP flag
+     but this might be wrong if we deleted the group section.  */
+  for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+    if (elf_section_type (isec) == SHT_GROUP
+       && isec->output_section == NULL)
+      {
+       asection *first = elf_next_in_group (isec);
+       asection *s = first;
+       while (s != NULL)
+         {
+           if (s->output_section != NULL)
+             {
+               elf_section_flags (s->output_section) &= ~SHF_GROUP;
+               elf_group_name (s->output_section) = NULL;
+             }
+           s = elf_next_in_group (s);
+           if (s == first)
+             break;
+         }
+      }
+
   return TRUE;
 }
 
@@ -8260,12 +8309,12 @@ elfcore_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
       in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
       in.descpos = offset + (in.descdata - buf);
 
-      if (strncmp (in.namedata, "NetBSD-CORE", 11) == 0)
+      if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
         {
           if (! elfcore_grok_netbsd_note (abfd, &in))
             goto error;
         }
-      else if (strncmp (in.namedata, "QNX", 3) == 0)
+      else if (CONST_STRNEQ (in.namedata, "QNX"))
        {
          if (! elfcore_grok_nto_note (abfd, &in))
            goto error;
@@ -8644,10 +8693,8 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2)
 
   /* If both are .gnu.linkonce sections, they have to have the same
      section name.  */
-  if (strncmp (sec1->name, ".gnu.linkonce",
-              sizeof ".gnu.linkonce" - 1) == 0
-      && strncmp (sec2->name, ".gnu.linkonce",
-                 sizeof ".gnu.linkonce" - 1) == 0)
+  if (CONST_STRNEQ (sec1->name, ".gnu.linkonce")
+      && CONST_STRNEQ (sec2->name, ".gnu.linkonce"))
     return strcmp (sec1->name + sizeof ".gnu.linkonce",
                   sec2->name + sizeof ".gnu.linkonce") == 0;
 
This page took 0.033465 seconds and 4 git commands to generate.