1999-05-28 Martin Dorey <mdorey@madge.com>
[binutils-gdb.git] / bfd / elf.c
index b4328c588fda113e7b8d9acd4ed438995439d3ac..36a4b6bd1e76df4eb9ebf19531b51997aba06376 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1,5 +1,5 @@
 /* ELF executable support for BFD.
-   Copyright 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+   Copyright 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -866,6 +866,7 @@ _bfd_elf_link_hash_newfunc (entry, table, string)
       ret->linker_section_pointer = (elf_linker_section_pointers_t *)0;
       ret->verinfo.verdef = NULL;
       ret->vtable_entries_used = NULL;
+      ret->vtable_entries_size = 0;
       ret->vtable_parent = NULL;
       ret->type = STT_NOTYPE;
       ret->other = 0;
@@ -1489,13 +1490,13 @@ elf_fake_sections (abfd, asect, failedptrarg)
       this_hdr->sh_type = SHT_DYNAMIC;
       this_hdr->sh_entsize = bed->s->sizeof_dyn;
     }
-  else if (strncmp (asect->name, ".rela", 5) == 0
+  else if (strncmp (asect->name, ".rela.", 6) == 0
           && get_elf_backend_data (abfd)->use_rela_p)
     {
       this_hdr->sh_type = SHT_RELA;
       this_hdr->sh_entsize = bed->s->sizeof_rela;
     }
-  else if (strncmp (asect->name, ".rel", 4) == 0
+  else if (strncmp (asect->name, ".rel.", 5) == 0
           && ! get_elf_backend_data (abfd)->use_rela_p)
     {
       this_hdr->sh_type = SHT_REL;
@@ -1631,7 +1632,7 @@ assign_section_numbers (abfd)
   elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
   t->shstrtab_hdr.sh_size = _bfd_stringtab_size (elf_shstrtab (abfd));
 
-  if (abfd->symcount > 0)
+  if (bfd_get_symcount (abfd) > 0)
     {
       t->symtab_section = section_number++;
       t->strtab_section = section_number++;
@@ -1658,7 +1659,7 @@ assign_section_numbers (abfd)
   elf_elfsections (abfd) = i_shdrp;
 
   i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr;
-  if (abfd->symcount > 0)
+  if (bfd_get_symcount (abfd) > 0)
     {
       i_shdrp[t->symtab_section] = &t->symtab_hdr;
       i_shdrp[t->strtab_section] = &t->strtab_hdr;
@@ -1800,6 +1801,7 @@ elf_map_symbols (abfd)
   int idx;
   asection *asect;
   asymbol **new_syms;
+  asymbol *sym;
 
 #ifdef DEBUG
   fprintf (stderr, "elf_map_symbols\n");
@@ -1822,19 +1824,36 @@ elf_map_symbols (abfd)
 
   for (idx = 0; idx < symcount; idx++)
     {
-      if ((syms[idx]->flags & BSF_SECTION_SYM) != 0
-         && syms[idx]->value == 0)
+      sym = syms[idx];
+      
+      if ((sym->flags & BSF_SECTION_SYM) != 0
+         && sym->value == 0)
        {
          asection *sec;
 
-         sec = syms[idx]->section;
+         sec = sym->section;
+
          if (sec->owner != NULL)
            {
              if (sec->owner != abfd)
                {
                  if (sec->output_offset != 0)
                    continue;
+                 
                  sec = sec->output_section;
+
+                 /* Empty sections in the input files may have had a section
+                    symbol created for them.  (See the comment near the end of
+                    _bfd_generic_link_output_symbols in linker.c).  If the linker
+                    script discards such sections then we will reach this point.
+                    Since we know that we cannot avoid this case, we detect it
+                    and skip the abort and the assignment to the sect_syms array.
+                    To reproduce this particular case try running the linker
+                    testsuite test ld-scripts/weak.exp for an ELF port that uses
+                    the generic linker.  */
+                 if (sec->owner == NULL)
+                   continue;
+
                  BFD_ASSERT (sec->owner == abfd);
                }
              sect_syms[sec->index] = syms[idx];
@@ -1844,8 +1863,6 @@ elf_map_symbols (abfd)
 
   for (asect = abfd->sections; asect; asect = asect->next)
     {
-      asymbol *sym;
-
       if (sect_syms[asect->index] != NULL)
        continue;
 
@@ -2003,7 +2020,7 @@ _bfd_elf_compute_section_file_positions (abfd, link_info)
     return false;
 
   /* The backend linker builds symbol table information itself.  */
-  if (link_info == NULL && abfd->symcount > 0)
+  if (link_info == NULL && bfd_get_symcount (abfd) > 0)
     {
       /* Non-zero if doing a relocatable link.  */
       int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
@@ -2027,7 +2044,7 @@ _bfd_elf_compute_section_file_positions (abfd, link_info)
   if (!assign_file_positions_except_relocs (abfd))
     return false;
 
-  if (link_info == NULL && abfd->symcount > 0)
+  if (link_info == NULL && bfd_get_symcount (abfd) > 0)
     {
       file_ptr off;
       Elf_Internal_Shdr *hdr;
@@ -2510,8 +2527,21 @@ assign_file_positions_for_segments (abfd)
          if ((abfd->flags & D_PAGED) != 0)
            off += (m->sections[0]->vma - off) % bed->maxpagesize;
          else
-           off += ((m->sections[0]->vma - off)
-                   % (1 << bfd_get_section_alignment (abfd, m->sections[0])));
+           {
+             bfd_size_type align;
+
+             align = 0;
+             for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
+               {
+                 bfd_size_type secalign;
+
+                 secalign = bfd_get_section_alignment (abfd, *secpp);
+                 if (secalign > align)
+                   align = secalign;
+               }
+
+             off += (m->sections[0]->vma - off) % (1 << align);
+           }
        }
 
       if (m->count == 0)
@@ -2607,7 +2637,7 @@ assign_file_positions_for_segments (abfd)
        }
 
       if (p->p_type == PT_LOAD
-         || (p->p_type == PT_NOTE && abfd->format == bfd_core))
+         || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
        {
          if (! m->includes_filehdr && ! m->includes_phdrs)
            p->p_offset = off;
@@ -2706,7 +2736,7 @@ assign_file_positions_for_segments (abfd)
                voff += sec->_raw_size;
            }
 
-         if (p->p_type == PT_NOTE && abfd->format == bfd_core)
+         if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
            {
              if (i == 0)       /* the actual "note" segment */
                {               /* this one actually contains everything. */
@@ -2731,7 +2761,8 @@ assign_file_positions_for_segments (abfd)
              if ((flags & SEC_LOAD) != 0)
                p->p_filesz += sec->_raw_size;
 
-             if (align > p->p_align)
+             if (align > p->p_align
+                 && (p->p_type != PT_LOAD || (abfd->flags & D_PAGED) == 0))
                p->p_align = align;
            }
 
@@ -2894,7 +2925,7 @@ assign_file_positions_except_relocs (abfd)
   struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
-      && abfd->format != bfd_core)
+      && bfd_get_format (abfd) != bfd_core)
     {
       Elf_Internal_Shdr **hdrpp;
       unsigned int i;
@@ -3046,6 +3077,9 @@ prep_headers (abfd)
     case bfd_arch_i860:
       i_ehdrp->e_machine = EM_860;
       break;
+    case bfd_arch_i960:
+      i_ehdrp->e_machine = EM_960;
+      break;
     case bfd_arch_mips:        /* MIPS Rxxxx */
       i_ehdrp->e_machine = EM_MIPS;    /* only MIPS R3000 */
       break;
@@ -3070,6 +3104,9 @@ prep_headers (abfd)
     case bfd_arch_fr30:
       i_ehdrp->e_machine = EM_CYGNUS_FR30;
       break;
+    case bfd_arch_mcore:
+      i_ehdrp->e_machine = EM_MCORE;
+      break;
     case bfd_arch_v850:
       switch (bfd_get_mach (abfd))
        {
@@ -3371,7 +3408,7 @@ copy_private_bfd_data (ibfd, obfd)
 
 #define IS_COREFILE_NOTE(p, s)                                          \
            (p->p_type == PT_NOTE                                       \
-            && ibfd->format == bfd_core                                \
+            && bfd_get_format (ibfd) == bfd_core                       \
             && s->vma == 0 && s->lma == 0                              \
             && (bfd_vma) s->filepos >= p->p_offset                     \
             && (bfd_vma) s->filepos + s->_raw_size                     \
@@ -3443,6 +3480,8 @@ copy_private_bfd_data (ibfd, obfd)
       m->includes_filehdr = (p->p_offset == 0
                             && p->p_filesz >= iehdr->e_ehsize);
 
+      m->includes_phdrs = 0;
+
       if (! phdr_included || p->p_type != PT_LOAD)
        {
          m->includes_phdrs =
@@ -4923,6 +4962,16 @@ elfcore_grok_prfpreg (abfd, note)
   return true;
 }
 
+#if defined (HAVE_PRPSINFO_T)
+# define elfcore_psinfo_t prpsinfo_t
+#endif
+
+#if defined (HAVE_PSINFO_T)
+# define elfcore_psinfo_t psinfo_t
+#endif
+
+
+#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
 
 /* return a malloc'ed copy of a string at START which is at
    most MAX bytes long, possibly without a terminating '\0'.
@@ -4953,17 +5002,6 @@ elfcore_strndup (abfd, start, max)
   return dup;
 }
 
-
-#if defined (HAVE_PRPSINFO_T)
-# define elfcore_psinfo_t prpsinfo_t
-#endif
-
-#if defined (HAVE_PSINFO_T)
-# define elfcore_psinfo_t psinfo_t
-#endif
-
-
-#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
 static boolean
 elfcore_grok_psinfo (abfd, note)
      bfd* abfd;