* elf-bfd.h (struct bfd_elf_section_data): Rename "group" to
[deliverable/binutils-gdb.git] / bfd / elf.c
index 5b2114fb0c3556a7638a1e3b8398bba568117e7f..30104185a434c681a8950f6397f8144c63d73a0b 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -50,17 +50,25 @@ static boolean assign_file_positions_except_relocs PARAMS ((bfd *));
 static boolean prep_headers PARAMS ((bfd *));
 static boolean swap_out_syms PARAMS ((bfd *, struct bfd_strtab_hash **, int));
 static boolean copy_private_bfd_data PARAMS ((bfd *, bfd *));
-static char *elf_read PARAMS ((bfd *, long, unsigned int));
+static char *elf_read PARAMS ((bfd *, file_ptr, bfd_size_type));
+static boolean setup_group PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
 static void elf_fake_sections PARAMS ((bfd *, asection *, PTR));
+static void set_group_contents PARAMS ((bfd *, asection *, PTR));
 static boolean assign_section_numbers PARAMS ((bfd *));
 static INLINE int sym_is_global PARAMS ((bfd *, asymbol *));
 static boolean elf_map_symbols PARAMS ((bfd *));
 static bfd_size_type get_program_header_size PARAMS ((bfd *));
-static boolean elfcore_read_notes PARAMS ((bfd *, bfd_vma, bfd_vma));
-static boolean elf_find_function PARAMS ((bfd *, asection *,
-                                         asymbol **,
-                                         bfd_vma, const char **,
-                                         const char **));
+static boolean elfcore_read_notes PARAMS ((bfd *, file_ptr, bfd_size_type));
+static boolean elf_find_function PARAMS ((bfd *, asection *, asymbol **,
+                                         bfd_vma, const char **,
+                                         const char **));
+static int elfcore_make_pid PARAMS ((bfd *));
+static boolean elfcore_maybe_make_sect PARAMS ((bfd *, char *, asection *));
+static boolean elfcore_make_note_pseudosection PARAMS ((bfd *, char *,
+                                                       Elf_Internal_Note *));
+static boolean elfcore_grok_prfpreg PARAMS ((bfd *, Elf_Internal_Note *));
+static boolean elfcore_grok_prxfpreg PARAMS ((bfd *, Elf_Internal_Note *));
+static boolean elfcore_grok_note PARAMS ((bfd *, Elf_Internal_Note *));
 
 /* Swap version information in and out.  The version information is
    currently size independent.  If that ever changes, this code will
@@ -74,13 +82,13 @@ _bfd_elf_swap_verdef_in (abfd, src, dst)
      const Elf_External_Verdef *src;
      Elf_Internal_Verdef *dst;
 {
-  dst->vd_version = bfd_h_get_16 (abfd, src->vd_version);
-  dst->vd_flags   = bfd_h_get_16 (abfd, src->vd_flags);
-  dst->vd_ndx     = bfd_h_get_16 (abfd, src->vd_ndx);
-  dst->vd_cnt     = bfd_h_get_16 (abfd, src->vd_cnt);
-  dst->vd_hash    = bfd_h_get_32 (abfd, src->vd_hash);
-  dst->vd_aux     = bfd_h_get_32 (abfd, src->vd_aux);
-  dst->vd_next    = bfd_h_get_32 (abfd, src->vd_next);
+  dst->vd_version = H_GET_16 (abfd, src->vd_version);
+  dst->vd_flags   = H_GET_16 (abfd, src->vd_flags);
+  dst->vd_ndx     = H_GET_16 (abfd, src->vd_ndx);
+  dst->vd_cnt     = H_GET_16 (abfd, src->vd_cnt);
+  dst->vd_hash    = H_GET_32 (abfd, src->vd_hash);
+  dst->vd_aux     = H_GET_32 (abfd, src->vd_aux);
+  dst->vd_next    = H_GET_32 (abfd, src->vd_next);
 }
 
 /* Swap out a Verdef structure.  */
@@ -91,13 +99,13 @@ _bfd_elf_swap_verdef_out (abfd, src, dst)
      const Elf_Internal_Verdef *src;
      Elf_External_Verdef *dst;
 {
-  bfd_h_put_16 (abfd, src->vd_version, dst->vd_version);
-  bfd_h_put_16 (abfd, src->vd_flags, dst->vd_flags);
-  bfd_h_put_16 (abfd, src->vd_ndx, dst->vd_ndx);
-  bfd_h_put_16 (abfd, src->vd_cnt, dst->vd_cnt);
-  bfd_h_put_32 (abfd, src->vd_hash, dst->vd_hash);
-  bfd_h_put_32 (abfd, src->vd_aux, dst->vd_aux);
-  bfd_h_put_32 (abfd, src->vd_next, dst->vd_next);
+  H_PUT_16 (abfd, src->vd_version, dst->vd_version);
+  H_PUT_16 (abfd, src->vd_flags, dst->vd_flags);
+  H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx);
+  H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt);
+  H_PUT_32 (abfd, src->vd_hash, dst->vd_hash);
+  H_PUT_32 (abfd, src->vd_aux, dst->vd_aux);
+  H_PUT_32 (abfd, src->vd_next, dst->vd_next);
 }
 
 /* Swap in a Verdaux structure.  */
@@ -108,8 +116,8 @@ _bfd_elf_swap_verdaux_in (abfd, src, dst)
      const Elf_External_Verdaux *src;
      Elf_Internal_Verdaux *dst;
 {
-  dst->vda_name = bfd_h_get_32 (abfd, src->vda_name);
-  dst->vda_next = bfd_h_get_32 (abfd, src->vda_next);
+  dst->vda_name = H_GET_32 (abfd, src->vda_name);
+  dst->vda_next = H_GET_32 (abfd, src->vda_next);
 }
 
 /* Swap out a Verdaux structure.  */
@@ -120,8 +128,8 @@ _bfd_elf_swap_verdaux_out (abfd, src, dst)
      const Elf_Internal_Verdaux *src;
      Elf_External_Verdaux *dst;
 {
-  bfd_h_put_32 (abfd, src->vda_name, dst->vda_name);
-  bfd_h_put_32 (abfd, src->vda_next, dst->vda_next);
+  H_PUT_32 (abfd, src->vda_name, dst->vda_name);
+  H_PUT_32 (abfd, src->vda_next, dst->vda_next);
 }
 
 /* Swap in a Verneed structure.  */
@@ -132,11 +140,11 @@ _bfd_elf_swap_verneed_in (abfd, src, dst)
      const Elf_External_Verneed *src;
      Elf_Internal_Verneed *dst;
 {
-  dst->vn_version = bfd_h_get_16 (abfd, src->vn_version);
-  dst->vn_cnt     = bfd_h_get_16 (abfd, src->vn_cnt);
-  dst->vn_file    = bfd_h_get_32 (abfd, src->vn_file);
-  dst->vn_aux     = bfd_h_get_32 (abfd, src->vn_aux);
-  dst->vn_next    = bfd_h_get_32 (abfd, src->vn_next);
+  dst->vn_version = H_GET_16 (abfd, src->vn_version);
+  dst->vn_cnt     = H_GET_16 (abfd, src->vn_cnt);
+  dst->vn_file    = H_GET_32 (abfd, src->vn_file);
+  dst->vn_aux     = H_GET_32 (abfd, src->vn_aux);
+  dst->vn_next    = H_GET_32 (abfd, src->vn_next);
 }
 
 /* Swap out a Verneed structure.  */
@@ -147,11 +155,11 @@ _bfd_elf_swap_verneed_out (abfd, src, dst)
      const Elf_Internal_Verneed *src;
      Elf_External_Verneed *dst;
 {
-  bfd_h_put_16 (abfd, src->vn_version, dst->vn_version);
-  bfd_h_put_16 (abfd, src->vn_cnt, dst->vn_cnt);
-  bfd_h_put_32 (abfd, src->vn_file, dst->vn_file);
-  bfd_h_put_32 (abfd, src->vn_aux, dst->vn_aux);
-  bfd_h_put_32 (abfd, src->vn_next, dst->vn_next);
+  H_PUT_16 (abfd, src->vn_version, dst->vn_version);
+  H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt);
+  H_PUT_32 (abfd, src->vn_file, dst->vn_file);
+  H_PUT_32 (abfd, src->vn_aux, dst->vn_aux);
+  H_PUT_32 (abfd, src->vn_next, dst->vn_next);
 }
 
 /* Swap in a Vernaux structure.  */
@@ -162,11 +170,11 @@ _bfd_elf_swap_vernaux_in (abfd, src, dst)
      const Elf_External_Vernaux *src;
      Elf_Internal_Vernaux *dst;
 {
-  dst->vna_hash  = bfd_h_get_32 (abfd, src->vna_hash);
-  dst->vna_flags = bfd_h_get_16 (abfd, src->vna_flags);
-  dst->vna_other = bfd_h_get_16 (abfd, src->vna_other);
-  dst->vna_name  = bfd_h_get_32 (abfd, src->vna_name);
-  dst->vna_next  = bfd_h_get_32 (abfd, src->vna_next);
+  dst->vna_hash  = H_GET_32 (abfd, src->vna_hash);
+  dst->vna_flags = H_GET_16 (abfd, src->vna_flags);
+  dst->vna_other = H_GET_16 (abfd, src->vna_other);
+  dst->vna_name  = H_GET_32 (abfd, src->vna_name);
+  dst->vna_next  = H_GET_32 (abfd, src->vna_next);
 }
 
 /* Swap out a Vernaux structure.  */
@@ -177,11 +185,11 @@ _bfd_elf_swap_vernaux_out (abfd, src, dst)
      const Elf_Internal_Vernaux *src;
      Elf_External_Vernaux *dst;
 {
-  bfd_h_put_32 (abfd, src->vna_hash, dst->vna_hash);
-  bfd_h_put_16 (abfd, src->vna_flags, dst->vna_flags);
-  bfd_h_put_16 (abfd, src->vna_other, dst->vna_other);
-  bfd_h_put_32 (abfd, src->vna_name, dst->vna_name);
-  bfd_h_put_32 (abfd, src->vna_next, dst->vna_next);
+  H_PUT_32 (abfd, src->vna_hash, dst->vna_hash);
+  H_PUT_16 (abfd, src->vna_flags, dst->vna_flags);
+  H_PUT_16 (abfd, src->vna_other, dst->vna_other);
+  H_PUT_32 (abfd, src->vna_name, dst->vna_name);
+  H_PUT_32 (abfd, src->vna_next, dst->vna_next);
 }
 
 /* Swap in a Versym structure.  */
@@ -192,7 +200,7 @@ _bfd_elf_swap_versym_in (abfd, src, dst)
      const Elf_External_Versym *src;
      Elf_Internal_Versym *dst;
 {
-  dst->vs_vers = bfd_h_get_16 (abfd, src->vs_vers);
+  dst->vs_vers = H_GET_16 (abfd, src->vs_vers);
 }
 
 /* Swap out a Versym structure.  */
@@ -203,7 +211,7 @@ _bfd_elf_swap_versym_out (abfd, src, dst)
      const Elf_Internal_Versym *src;
      Elf_External_Versym *dst;
 {
-  bfd_h_put_16 (abfd, src->vs_vers, dst->vs_vers);
+  H_PUT_16 (abfd, src->vs_vers, dst->vs_vers);
 }
 
 /* Standard ELF hash function.  Do not change this function; you will
@@ -239,16 +247,16 @@ bfd_elf_hash (namearg)
 static char *
 elf_read (abfd, offset, size)
      bfd *abfd;
-     long offset;
-     unsigned int size;
+     file_ptr offset;
+     bfd_size_type size;
 {
   char *buf;
 
   if ((buf = bfd_alloc (abfd, size)) == NULL)
     return NULL;
-  if (bfd_seek (abfd, offset, SEEK_SET) == -1)
+  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
     return NULL;
-  if (bfd_read ((PTR) buf, size, 1, abfd) != size)
+  if (bfd_bread ((PTR) buf, size, abfd) != size)
     {
       if (bfd_get_error () != bfd_error_system_call)
        bfd_set_error (bfd_error_file_truncated);
@@ -263,8 +271,8 @@ bfd_elf_mkobject (abfd)
 {
   /* This just does initialization.  */
   /* coff_mkobject zalloc's space for tdata.coff_obj_data ...  */
-  elf_tdata (abfd) = (struct elf_obj_tdata *)
-    bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
+  bfd_size_type amt = sizeof (struct elf_obj_tdata);
+  elf_tdata (abfd) = (struct elf_obj_tdata *) bfd_zalloc (abfd, amt);
   if (elf_tdata (abfd) == 0)
     return false;
   /* Since everything is done at close time, do we need any
@@ -288,8 +296,8 @@ bfd_elf_get_str_section (abfd, shindex)
 {
   Elf_Internal_Shdr **i_shdrp;
   char *shstrtab = NULL;
-  unsigned int offset;
-  unsigned int shstrtabsize;
+  file_ptr offset;
+  bfd_size_type shstrtabsize;
 
   i_shdrp = elf_elfsections (abfd);
   if (i_shdrp == 0 || i_shdrp[shindex] == 0)
@@ -328,7 +336,7 @@ bfd_elf_string_from_elf_section (abfd, shindex, strindex)
     {
       (*_bfd_error_handler)
        (_("%s: invalid string offset %u >= %lu for section `%s'"),
-        bfd_get_filename (abfd), strindex, (unsigned long) hdr->sh_size,
+        bfd_archive_filename (abfd), strindex, (unsigned long) hdr->sh_size,
         ((shindex == elf_elfheader(abfd)->e_shstrndx
           && strindex == hdr->sh_name)
          ? ".shstrtab"
@@ -339,6 +347,186 @@ bfd_elf_string_from_elf_section (abfd, shindex, strindex)
   return ((char *) hdr->contents) + strindex;
 }
 
+/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
+   sections.  The first element is the flags, the rest are section
+   pointers.  */
+
+typedef union elf_internal_group {
+  Elf_Internal_Shdr *shdr;
+  unsigned int flags;
+} Elf_Internal_Group;
+
+/* Set next_in_group list pointer, and group name for NEWSECT.  */
+
+static boolean
+setup_group (abfd, hdr, newsect)
+     bfd *abfd;
+     Elf_Internal_Shdr *hdr;
+     asection *newsect;
+{
+  unsigned int num_group = elf_tdata (abfd)->num_group;
+
+  /* If num_group is zero, read in all SHT_GROUP sections.  The count
+     is set to -1 if there are no SHT_GROUP sections.  */
+  if (num_group == 0)
+    {
+      unsigned int i, shnum;
+
+      /* First count the number of groups.  If we have a SHT_GROUP
+        section with just a flag word (ie. sh_size is 4), ignore it.  */
+      shnum = elf_elfheader (abfd)->e_shnum;
+      num_group = 0;
+      for (i = 0; i < shnum; i++)
+       {
+         Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
+         if (shdr->sh_type == SHT_GROUP && shdr->sh_size >= 8)
+           num_group += 1;
+       }
+
+      if (num_group == 0)
+       num_group = -1;
+      elf_tdata (abfd)->num_group = num_group;
+
+      if (num_group > 0)
+       {
+         /* We keep a list of elf section headers for group sections,
+            so we can find them quickly.  */
+         bfd_size_type amt = num_group * sizeof (Elf_Internal_Shdr *);
+         elf_tdata (abfd)->group_sect_ptr = bfd_alloc (abfd, amt);
+         if (elf_tdata (abfd)->group_sect_ptr == NULL)
+           return false;
+
+         num_group = 0;
+         for (i = 0; i < shnum; i++)
+           {
+             Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
+             if (shdr->sh_type == SHT_GROUP && shdr->sh_size >= 8)
+               {
+                 char *src;
+                 Elf_Internal_Group *dest;
+
+                 /* Add to list of sections.  */
+                 elf_tdata (abfd)->group_sect_ptr[num_group] = shdr;
+                 num_group += 1;
+
+                 /* Read the raw contents.  */
+                 BFD_ASSERT (sizeof (*dest) >= 4);
+                 amt = shdr->sh_size * sizeof (*dest) / 4;
+                 shdr->contents = bfd_alloc (abfd, amt);
+                 if (shdr->contents == NULL
+                     || bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
+                     || (bfd_bread (shdr->contents, shdr->sh_size, abfd)
+                         != shdr->sh_size))
+                   return false;
+
+                 /* Translate raw contents, a flag word followed by an
+                    array of elf section indices all in target byte order,
+                    to the flag word followed by an array of elf section
+                    pointers.  */
+                 src = shdr->contents + shdr->sh_size;
+                 dest = (Elf_Internal_Group *) (shdr->contents + amt);
+                 while (1)
+                   {
+                     unsigned int idx;
+
+                     src -= 4;
+                     --dest;
+                     idx = H_GET_32 (abfd, src);
+                     if (src == shdr->contents)
+                       {
+                         dest->flags = idx;
+                         break;
+                       }
+                     if (idx >= shnum)
+                       {
+                         ((*_bfd_error_handler)
+                          (_("%s: invalid SHT_GROUP entry"),
+                           bfd_archive_filename (abfd)));
+                         idx = 0;
+                       }
+                     dest->shdr = elf_elfsections (abfd)[idx];
+                   }
+               }
+           }
+       }
+    }
+
+  if (num_group != (unsigned) -1)
+    {
+      unsigned int i;
+
+      for (i = 0; i < num_group; i++)
+       {
+         Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
+         Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
+         unsigned int n_elt = shdr->sh_size / 4;
+
+         /* Look through this group's sections to see if current
+            section is a member.  */
+         while (--n_elt != 0)
+           if ((++idx)->shdr == hdr)
+             {
+               asection *s;
+
+               /* We are a member of this group.  Go looking through
+                  other members to see if any others are linked via
+                  next_in_group.  */
+               idx = (Elf_Internal_Group *) shdr->contents;
+               n_elt = shdr->sh_size / 4;
+               while (--n_elt != 0)
+                 if ((s = (++idx)->shdr->bfd_section) != NULL
+                     && elf_next_in_group (s) != NULL)
+                   break;
+               if (n_elt != 0)
+                 {
+                   /* Snarf the group name from other member, and
+                      insert current section in circular list.  */
+                   elf_group_name (newsect) = elf_group_name (s);
+                   elf_next_in_group (newsect) = elf_next_in_group (s);
+                   elf_next_in_group (s) = newsect;
+                 }
+               else
+                 {
+                   struct elf_backend_data *bed;
+                   file_ptr pos;
+                   unsigned char ename[4];
+                   unsigned long iname;
+                   const char *gname;
+
+                   /* Humbug.  Get the name from the group signature
+                      symbol.  Why isn't the signature just a string?
+                      Fortunately, the name index is at the same
+                      place in the external symbol for both 32 and 64
+                      bit ELF.  */
+                   bed = get_elf_backend_data (abfd);
+                   pos = elf_tdata (abfd)->symtab_hdr.sh_offset;
+                   pos += shdr->sh_info * bed->s->sizeof_sym;
+                   if (bfd_seek (abfd, pos, SEEK_SET) != 0
+                       || bfd_bread (ename, 4, abfd) != 4)
+                     return false;
+                   iname = H_GET_32 (abfd, ename);
+                   gname = elf_string_from_elf_strtab (abfd, iname);
+                   elf_group_name (newsect) = gname;
+
+                   /* Start a circular list with one element.  */
+                   elf_next_in_group (newsect) = newsect;
+                 }
+               if (shdr->bfd_section != NULL)
+                 elf_next_in_group (shdr->bfd_section) = newsect;
+               i = num_group - 1;
+               break;
+             }
+       }
+    }
+
+  if (elf_group_name (newsect) == NULL)
+    {
+      (*_bfd_error_handler) (_("%s: no group info for section %s"),
+                            bfd_archive_filename (abfd), newsect->name);
+    }
+  return true;
+}
+
 /* Make a BFD section from an ELF section.  We store a pointer to the
    BFD section in the bfd_section field of the header.  */
 
@@ -368,12 +556,14 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name)
   if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
       || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
       || ! bfd_set_section_alignment (abfd, newsect,
-                                     bfd_log2 (hdr->sh_addralign)))
+                                     bfd_log2 ((bfd_vma) hdr->sh_addralign)))
     return false;
 
   flags = SEC_NO_FLAGS;
   if (hdr->sh_type != SHT_NOBITS)
     flags |= SEC_HAS_CONTENTS;
+  if (hdr->sh_type == SHT_GROUP)
+    flags |= SEC_GROUP | SEC_EXCLUDE;
   if ((hdr->sh_flags & SHF_ALLOC) != 0)
     {
       flags |= SEC_ALLOC;
@@ -393,6 +583,9 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name)
       if ((hdr->sh_flags & SHF_STRINGS) != 0)
        flags |= SEC_STRINGS;
     }
+  if (hdr->sh_flags & SHF_GROUP)
+    if (!setup_group (abfd, hdr, newsect))
+      return false;
 
   /* The debugging sections appear to be recognized only by name, not
      any sort of flag.  */
@@ -565,6 +758,8 @@ _bfd_elf_merge_sections (abfd, info)
      bfd *abfd;
      struct bfd_link_info *info;
 {
+  if (!is_elf_hash_table (info))
+    return false;
   if (elf_hash_table (info)->merge_info)
     _bfd_merge_sections (abfd, elf_hash_table (info)->merge_info);
   return true;
@@ -591,37 +786,37 @@ _bfd_elf_print_private_bfd_data (abfd, farg)
       c = elf_elfheader (abfd)->e_phnum;
       for (i = 0; i < c; i++, p++)
        {
-         const char *s;
+         const char *pt;
          char buf[20];
 
          switch (p->p_type)
            {
-           case PT_NULL: s = "NULL"; break;
-           case PT_LOAD: s = "LOAD"; break;
-           case PT_DYNAMIC: s = "DYNAMIC"; break;
-           case PT_INTERP: s = "INTERP"; break;
-           case PT_NOTE: s = "NOTE"; break;
-           case PT_SHLIB: s = "SHLIB"; break;
-           case PT_PHDR: s = "PHDR"; break;
-           default: sprintf (buf, "0x%lx", p->p_type); s = buf; break;
+           case PT_NULL: pt = "NULL"; break;
+           case PT_LOAD: pt = "LOAD"; break;
+           case PT_DYNAMIC: pt = "DYNAMIC"; break;
+           case PT_INTERP: pt = "INTERP"; break;
+           case PT_NOTE: pt = "NOTE"; break;
+           case PT_SHLIB: pt = "SHLIB"; break;
+           case PT_PHDR: pt = "PHDR"; break;
+           default: sprintf (buf, "0x%lx", p->p_type); pt = buf; break;
            }
-         fprintf (f, "%8s off    0x", s);
-         fprintf_vma (f, p->p_offset);
+         fprintf (f, "%8s off    0x", pt);
+         bfd_fprintf_vma (abfd, f, p->p_offset);
          fprintf (f, " vaddr 0x");
-         fprintf_vma (f, p->p_vaddr);
+         bfd_fprintf_vma (abfd, f, p->p_vaddr);
          fprintf (f, " paddr 0x");
-         fprintf_vma (f, p->p_paddr);
+         bfd_fprintf_vma (abfd, f, p->p_paddr);
          fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
          fprintf (f, "         filesz 0x");
-         fprintf_vma (f, p->p_filesz);
+         bfd_fprintf_vma (abfd, f, p->p_filesz);
          fprintf (f, " memsz 0x");
-         fprintf_vma (f, p->p_memsz);
+         bfd_fprintf_vma (abfd, f, p->p_memsz);
          fprintf (f, " flags %c%c%c",
                   (p->p_flags & PF_R) != 0 ? 'r' : '-',
                   (p->p_flags & PF_W) != 0 ? 'w' : '-',
                   (p->p_flags & PF_X) != 0 ? 'x' : '-');
-         if ((p->p_flags &~ (PF_R | PF_W | PF_X)) != 0)
-           fprintf (f, " %lx", p->p_flags &~ (PF_R | PF_W | PF_X));
+         if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0)
+           fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X));
          fprintf (f, "\n");
        }
     }
@@ -630,7 +825,7 @@ _bfd_elf_print_private_bfd_data (abfd, farg)
   if (s != NULL)
     {
       int elfsec;
-      unsigned long link;
+      unsigned long shlink;
       bfd_byte *extdyn, *extdynend;
       size_t extdynsize;
       void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
@@ -647,7 +842,7 @@ _bfd_elf_print_private_bfd_data (abfd, farg)
       elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
       if (elfsec == -1)
        goto error_return;
-      link = elf_elfsections (abfd)[elfsec]->sh_link;
+      shlink = elf_elfsections (abfd)[elfsec]->sh_link;
 
       extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
       swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
@@ -739,9 +934,9 @@ _bfd_elf_print_private_bfd_data (abfd, farg)
          else
            {
              const char *string;
+             unsigned int tagv = dyn.d_un.d_val;
 
-             string = bfd_elf_string_from_elf_section (abfd, link,
-                                                       dyn.d_un.d_val);
+             string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
              if (string == NULL)
                goto error_return;
              fprintf (f, "%s", string);
@@ -824,7 +1019,7 @@ bfd_elf_print_symbol (abfd, filep, symbol, how)
       break;
     case bfd_print_symbol_more:
       fprintf (file, "elf ");
-      fprintf_vma (file, symbol->value);
+      bfd_fprintf_vma (abfd, file, symbol->value);
       fprintf (file, " %lx", (long) symbol->flags);
       break;
     case bfd_print_symbol_all:
@@ -833,6 +1028,7 @@ bfd_elf_print_symbol (abfd, filep, symbol, how)
        const char *name = NULL;
        struct elf_backend_data *bed;
        unsigned char st_other;
+       bfd_vma val;
 
        section_name = symbol->section ? symbol->section->name : "(*none*)";
 
@@ -843,7 +1039,7 @@ bfd_elf_print_symbol (abfd, filep, symbol, how)
        if (name == NULL)
          {
            name = symbol->name;
-           bfd_print_symbol_vandf ((PTR) file, symbol);
+           bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
          }
 
        fprintf (file, " %s\t", section_name);
@@ -851,10 +1047,11 @@ bfd_elf_print_symbol (abfd, filep, symbol, how)
           we've already printed the size; now print the alignment.
           For other symbols, we have no specified alignment, and
           we've printed the address; now print the size.  */
-       fprintf_vma (file,
-                    (bfd_is_com_section (symbol->section)
-                     ? ((elf_symbol_type *) symbol)->internal_elf_sym.st_value
-                     : ((elf_symbol_type *) symbol)->internal_elf_sym.st_size));
+       if (bfd_is_com_section (symbol->section))
+         val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
+       else
+         val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size;
+       bfd_fprintf_vma (abfd, file, val);
 
        /* If we have version information, print it.  */
        if (elf_tdata (abfd)->dynversym_section != 0
@@ -936,31 +1133,31 @@ _bfd_elf_link_hash_newfunc (entry, table, string)
      struct bfd_hash_table *table;
      const char *string;
 {
-  struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
-
   /* Allocate the structure if it has not already been allocated by a
      subclass.  */
-  if (ret == (struct elf_link_hash_entry *) NULL)
-    ret = ((struct elf_link_hash_entry *)
-          bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry)));
-  if (ret == (struct elf_link_hash_entry *) NULL)
-    return (struct bfd_hash_entry *) ret;
+  if (entry == NULL)
+    {
+      entry = bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
+      if (entry == NULL)
+       return entry;
+    }
 
   /* Call the allocation method of the superclass.  */
-  ret = ((struct elf_link_hash_entry *)
-        _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
-                                table, string));
-  if (ret != (struct elf_link_hash_entry *) NULL)
+  entry = _bfd_link_hash_newfunc (entry, table, string);
+  if (entry != NULL)
     {
+      struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
+      struct elf_link_hash_table *htab = (struct elf_link_hash_table *) table;
+
       /* Set local fields.  */
       ret->indx = -1;
       ret->size = 0;
       ret->dynindx = -1;
       ret->dynstr_index = 0;
       ret->weakdef = NULL;
-      ret->got.offset = (bfd_vma) -1;
-      ret->plt.offset = (bfd_vma) -1;
-      ret->linker_section_pointer = (elf_linker_section_pointers_t *)0;
+      ret->got.refcount = htab->init_refcount;
+      ret->plt.refcount = htab->init_refcount;
+      ret->linker_section_pointer = NULL;
       ret->verinfo.verdef = NULL;
       ret->vtable_entries_used = NULL;
       ret->vtable_entries_size = 0;
@@ -974,16 +1171,18 @@ _bfd_elf_link_hash_newfunc (entry, table, string)
       ret->elf_link_hash_flags = ELF_LINK_NON_ELF;
     }
 
-  return (struct bfd_hash_entry *) ret;
+  return entry;
 }
 
 /* Copy data from an indirect symbol to its direct symbol, hiding the
-   old indirect symbol.  */
+   old indirect symbol.  Also used for copying flags to a weakdef.  */
 
 void
 _bfd_elf_link_hash_copy_indirect (dir, ind)
      struct elf_link_hash_entry *dir, *ind;
 {
+  bfd_signed_vma tmp;
+
   /* Copy down any references that we may have already seen to the
      symbol which just became indirect.  */
 
@@ -994,21 +1193,28 @@ _bfd_elf_link_hash_copy_indirect (dir, ind)
        | ELF_LINK_HASH_REF_REGULAR_NONWEAK
        | ELF_LINK_NON_GOT_REF));
 
-  /* Copy over the global and procedure linkage table offset entries.
+  if (dir == ind->weakdef)
+    return;
+
+  /* Copy over the global and procedure linkage table refcount entries.
      These may have been already set up by a check_relocs routine.  */
-  if (dir->got.offset == (bfd_vma) -1)
+  tmp = dir->got.refcount;
+  if (tmp <= 0)
     {
-      dir->got.offset = ind->got.offset;
-      ind->got.offset = (bfd_vma) -1;
+      dir->got.refcount = ind->got.refcount;
+      ind->got.refcount = tmp;
     }
-  BFD_ASSERT (ind->got.offset == (bfd_vma) -1);
+  else
+    BFD_ASSERT (ind->got.refcount <= 0);
 
-  if (dir->plt.offset == (bfd_vma) -1)
+  tmp = dir->plt.refcount;
+  if (tmp <= 0)
     {
-      dir->plt.offset = ind->plt.offset;
-      ind->plt.offset = (bfd_vma) -1;
+      dir->plt.refcount = ind->plt.refcount;
+      ind->plt.refcount = tmp;
     }
-  BFD_ASSERT (ind->plt.offset == (bfd_vma) -1);
+  else
+    BFD_ASSERT (ind->plt.refcount <= 0);
 
   if (dir->dynindx == -1)
     {
@@ -1017,7 +1223,8 @@ _bfd_elf_link_hash_copy_indirect (dir, ind)
       ind->dynindx = -1;
       ind->dynstr_index = 0;
     }
-  BFD_ASSERT (ind->dynindx == -1);
+  else
+    BFD_ASSERT (ind->dynindx == -1);
 }
 
 void
@@ -1041,8 +1248,11 @@ _bfd_elf_link_hash_table_init (table, abfd, newfunc)
                                                struct bfd_hash_table *,
                                                const char *));
 {
+  boolean ret;
+
   table->dynamic_sections_created = false;
   table->dynobj = NULL;
+  table->init_refcount = get_elf_backend_data (abfd)->can_refcount - 1;
   /* The first dynamic symbol is a dummy.  */
   table->dynsymcount = 1;
   table->dynstr = NULL;
@@ -1053,7 +1263,10 @@ _bfd_elf_link_hash_table_init (table, abfd, newfunc)
   table->stab_info = NULL;
   table->merge_info = NULL;
   table->dynlocal = NULL;
-  return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
+  ret = _bfd_link_hash_table_init (& table->root, abfd, newfunc);
+  table->root.type = bfd_link_elf_hash_table;
+
+  return ret;
 }
 
 /* Create an ELF linker hash table.  */
@@ -1063,9 +1276,9 @@ _bfd_elf_link_hash_table_create (abfd)
      bfd *abfd;
 {
   struct elf_link_hash_table *ret;
+  bfd_size_type amt = sizeof (struct elf_link_hash_table);
 
-  ret = ((struct elf_link_hash_table *)
-        bfd_alloc (abfd, sizeof (struct elf_link_hash_table)));
+  ret = (struct elf_link_hash_table *) bfd_alloc (abfd, amt);
   if (ret == (struct elf_link_hash_table *) NULL)
     return NULL;
 
@@ -1154,7 +1367,7 @@ bfd_elf_get_bfd_needed_list (abfd, pneeded)
   asection *s;
   bfd_byte *dynbuf = NULL;
   int elfsec;
-  unsigned long link;
+  unsigned long shlink;
   bfd_byte *extdyn, *extdynend;
   size_t extdynsize;
   void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
@@ -1181,7 +1394,7 @@ bfd_elf_get_bfd_needed_list (abfd, pneeded)
   if (elfsec == -1)
     goto error_return;
 
-  link = elf_elfsections (abfd)[elfsec]->sh_link;
+  shlink = elf_elfsections (abfd)[elfsec]->sh_link;
 
   extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
   swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
@@ -1201,13 +1414,15 @@ bfd_elf_get_bfd_needed_list (abfd, pneeded)
        {
          const char *string;
          struct bfd_link_needed_list *l;
+         unsigned int tagv = dyn.d_un.d_val;
+         bfd_size_type amt;
 
-         string = bfd_elf_string_from_elf_section (abfd, link,
-                                                   dyn.d_un.d_val);
+         string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
          if (string == NULL)
            goto error_return;
 
-         l = (struct bfd_link_needed_list *) bfd_alloc (abfd, sizeof *l);
+         amt = sizeof *l;
+         l = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
          if (l == NULL)
            goto error_return;
 
@@ -1383,7 +1598,7 @@ bfd_section_from_shdr (abfd, shindex)
          {
            ((*_bfd_error_handler)
             (_("%s: invalid link %lu for reloc section %s (index %u)"),
-             bfd_get_filename (abfd), hdr->sh_link, name, shindex));
+             bfd_archive_filename (abfd), hdr->sh_link, name, shindex));
            return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
          }
 
@@ -1443,8 +1658,10 @@ bfd_section_from_shdr (abfd, shindex)
          hdr2 = &elf_section_data (target_sect)->rel_hdr;
        else
          {
+           bfd_size_type amt;
            BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL);
-           hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*hdr2));
+           amt = sizeof (*hdr2);
+           hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
            elf_section_data (target_sect)->rel_hdr2 = hdr2;
          }
        *hdr2 = *hdr;
@@ -1484,6 +1701,26 @@ bfd_section_from_shdr (abfd, shindex)
     case SHT_SHLIB:
       return true;
 
+    case SHT_GROUP:
+      /* Make a section for objcopy and relocatable links.  */
+      if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name))
+       return false;
+      if (hdr->contents != NULL)
+       {
+         Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
+         unsigned int n_elt = hdr->sh_size / 4;
+         asection *s;
+
+         while (--n_elt != 0)
+           if ((s = (++idx)->shdr->bfd_section) != NULL
+               && elf_next_in_group (s) != NULL)
+             {
+               elf_next_in_group (hdr->bfd_section) = s;
+               break;
+             }
+       }
+      break;
+
     default:
       /* Check for any processor-specific section types.  */
       {
@@ -1516,8 +1753,9 @@ _bfd_elf_new_section_hook (abfd, sec)
      asection *sec;
 {
   struct bfd_elf_section_data *sdata;
+  bfd_size_type amt = sizeof (*sdata);
 
-  sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd, sizeof (*sdata));
+  sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd, amt);
   if (!sdata)
     return false;
   sec->used_by_bfd = (PTR) sdata;
@@ -1567,7 +1805,7 @@ _bfd_elf_make_section_from_phdr (abfd, hdr, index, typename)
            && (hdr->p_filesz > 0)
            && (hdr->p_memsz > hdr->p_filesz));
   sprintf (namebuf, "%s%d%s", typename, index, split ? "a" : "");
-  name = bfd_alloc (abfd, strlen (namebuf) + 1);
+  name = bfd_alloc (abfd, (bfd_size_type) strlen (namebuf) + 1);
   if (!name)
     return false;
   strcpy (name, namebuf);
@@ -1598,7 +1836,7 @@ _bfd_elf_make_section_from_phdr (abfd, hdr, index, typename)
   if (split)
     {
       sprintf (namebuf, "%s%db", typename, index);
-      name = bfd_alloc (abfd, strlen (namebuf) + 1);
+      name = bfd_alloc (abfd, (bfd_size_type) strlen (namebuf) + 1);
       if (!name)
        return false;
       strcpy (name, namebuf);
@@ -1646,7 +1884,7 @@ bfd_section_from_phdr (abfd, hdr, index)
     case PT_NOTE:
       if (! _bfd_elf_make_section_from_phdr (abfd, hdr, index, "note"))
        return false;
-      if (! elfcore_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
+      if (! elfcore_read_notes (abfd, (file_ptr) hdr->p_offset, hdr->p_filesz))
        return false;
       return true;
 
@@ -1679,10 +1917,10 @@ _bfd_elf_init_reloc_shdr (abfd, rel_hdr, asect, use_rela_p)
      boolean use_rela_p;
 {
   char *name;
-  struct elf_backend_data *bed;
+  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  bfd_size_type amt = sizeof ".rela" + strlen (asect->name);
 
-  bed = get_elf_backend_data (abfd);
-  name = bfd_alloc (abfd, sizeof ".rela" + strlen (asect->name));
+  name = bfd_alloc (abfd, amt);
   if (name == NULL)
     return false;
   sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
@@ -1818,6 +2056,11 @@ elf_fake_sections (abfd, asect, failedptrarg)
        BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
                    || this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
     }
+  else if ((asect->flags & SEC_GROUP) != 0)
+    {
+      this_hdr->sh_type = SHT_GROUP;
+      this_hdr->sh_entsize = 4;
+    }
   else if ((asect->flags & SEC_ALLOC) != 0
           && ((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0))
     this_hdr->sh_type = SHT_NOBITS;
@@ -1837,6 +2080,8 @@ elf_fake_sections (abfd, asect, failedptrarg)
       if ((asect->flags & SEC_STRINGS) != 0)
        this_hdr->sh_flags |= SHF_STRINGS;
     }
+  if (elf_group_name (asect) != NULL)
+    this_hdr->sh_flags |= SHF_GROUP;
 
   /* Check for processor-specific section types.  */
   if (bed->elf_backend_fake_sections)
@@ -1854,6 +2099,83 @@ elf_fake_sections (abfd, asect, failedptrarg)
     *failedptr = true;
 }
 
+/* Fill in the contents of a SHT_GROUP section.  */
+
+static void
+set_group_contents (abfd, sec, failedptrarg)
+     bfd *abfd;
+     asection *sec;
+     PTR failedptrarg ATTRIBUTE_UNUSED;
+{
+  boolean *failedptr = (boolean *) failedptrarg;
+  unsigned long symindx;
+  asection *elt;
+  unsigned char *loc;
+  struct bfd_link_order *l;
+
+  if (elf_section_data (sec)->this_hdr.sh_type != SHT_GROUP
+      || *failedptr)
+    return;
+
+  /* If called from the assembler, swap_out_syms will have set up
+     elf_section_syms;  If called for "ld -r", the symbols won't yet
+     be mapped, so emulate elf_bfd_final_link.  */
+  if (elf_section_syms (abfd) != NULL)
+    symindx = elf_section_syms (abfd)[sec->index]->udata.i;
+  else
+    symindx = elf_section_data (sec)->this_idx;
+  elf_section_data (sec)->this_hdr.sh_info = symindx;
+
+  /* Nor will the contents be allocated for "ld -r".  */
+  if (sec->contents == NULL)
+    {
+      sec->contents = bfd_alloc (abfd, sec->_raw_size);
+      if (sec->contents == NULL)
+       {
+         *failedptr = true;
+         return;
+       }
+    }
+
+  loc = sec->contents + sec->_raw_size;
+
+  /* Get the pointer to the first section in the group that we
+     squirreled away here.  */
+  elt = elf_next_in_group (sec);
+
+  /* First element is a flag word.  Rest of section is elf section
+     indices for all the sections of the group.  Write them backwards
+     just to keep the group in the same order as given in .section
+     directives, not that it matters.  */
+  while (elt != NULL)
+    {
+      loc -= 4;
+      H_PUT_32 (abfd, elf_section_data (elt)->this_idx, loc);
+      elt = elf_next_in_group (elt);
+    }
+
+  /* If this is a relocatable link, then the above did nothing because
+     SEC is the output section.  Look through the input sections
+     instead.  */
+  for (l = sec->link_order_head; l != NULL; l = l->next)
+    if (l->type == bfd_indirect_link_order
+       && (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
+      do
+       {
+         loc -= 4;
+         H_PUT_32 (abfd,
+                   elf_section_data (elt->output_section)->this_idx, loc);
+         elt = elf_next_in_group (elt);
+         /* During a relocatable link, the lists are circular.  */
+       }
+      while (elt != elf_next_in_group (l->u.indirect.section));
+
+  loc -= 4;
+  H_PUT_32 (abfd, 0, loc);
+
+  BFD_ASSERT (loc == sec->contents);
+}
+
 /* Assign all ELF section numbers.  The dummy first section is handled here
    too.  The link/info pointers for the standard section types are filled
    in here too, while we're at it.  */
@@ -1866,6 +2188,7 @@ assign_section_numbers (abfd)
   asection *sec;
   unsigned int section_number;
   Elf_Internal_Shdr **i_shdrp;
+  bfd_size_type amt;
 
   section_number = 1;
 
@@ -1899,13 +2222,13 @@ assign_section_numbers (abfd)
 
   /* Set up the list of section header pointers, in agreement with the
      indices.  */
-  i_shdrp = ((Elf_Internal_Shdr **)
-            bfd_alloc (abfd, section_number * sizeof (Elf_Internal_Shdr *)));
+  amt = section_number * sizeof (Elf_Internal_Shdr *);
+  i_shdrp = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt);
   if (i_shdrp == NULL)
     return false;
 
-  i_shdrp[0] = ((Elf_Internal_Shdr *)
-               bfd_alloc (abfd, sizeof (Elf_Internal_Shdr)));
+  amt = sizeof (Elf_Internal_Shdr);
+  i_shdrp[0] = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
   if (i_shdrp[0] == NULL)
     {
       bfd_release (abfd, i_shdrp);
@@ -1987,7 +2310,7 @@ assign_section_numbers (abfd)
              char *alc;
 
              len = strlen (sec->name);
-             alc = (char *) bfd_malloc (len - 2);
+             alc = (char *) bfd_malloc ((bfd_size_type) len - 2);
              if (alc == NULL)
                return false;
              strncpy (alc, sec->name, len - 3);
@@ -2025,6 +2348,9 @@ assign_section_numbers (abfd)
          if (s != NULL)
            d->this_hdr.sh_link = elf_section_data (s)->this_idx;
          break;
+
+       case SHT_GROUP:
+         d->this_hdr.sh_link = t->symtab_section;
        }
     }
 
@@ -2053,19 +2379,19 @@ static boolean
 elf_map_symbols (abfd)
      bfd *abfd;
 {
-  int symcount = bfd_get_symcount (abfd);
+  unsigned int symcount = bfd_get_symcount (abfd);
   asymbol **syms = bfd_get_outsymbols (abfd);
   asymbol **sect_syms;
-  int num_locals = 0;
-  int num_globals = 0;
-  int num_locals2 = 0;
-  int num_globals2 = 0;
+  unsigned int num_locals = 0;
+  unsigned int num_globals = 0;
+  unsigned int num_locals2 = 0;
+  unsigned int num_globals2 = 0;
   int max_index = 0;
-  int num_sections = 0;
-  int idx;
+  unsigned int num_sections = 0;
+  unsigned int idx;
   asection *asect;
   asymbol **new_syms;
-  asymbol *sym;
+  bfd_size_type amt;
 
 #ifdef DEBUG
   fprintf (stderr, "elf_map_symbols\n");
@@ -2081,14 +2407,16 @@ elf_map_symbols (abfd)
     }
 
   max_index++;
-  sect_syms = (asymbol **) bfd_zalloc (abfd, max_index * sizeof (asymbol *));
+  amt = max_index * sizeof (asymbol *);
+  sect_syms = (asymbol **) bfd_zalloc (abfd, amt);
   if (sect_syms == NULL)
     return false;
   elf_section_syms (abfd) = sect_syms;
+  elf_num_section_syms (abfd) = max_index;
 
   for (idx = 0; idx < symcount; idx++)
     {
-      sym = syms[idx];
+      asymbol *sym = syms[idx];
 
       if ((sym->flags & BSF_SECTION_SYM) != 0
          && sym->value == 0)
@@ -2127,6 +2455,8 @@ elf_map_symbols (abfd)
 
   for (asect = abfd->sections; asect; asect = asect->next)
     {
+      asymbol *sym;
+
       if (sect_syms[asect->index] != NULL)
        continue;
 
@@ -2171,16 +2501,16 @@ elf_map_symbols (abfd)
     }
 
   /* Now sort the symbols so the local symbols are first.  */
-  new_syms = ((asymbol **)
-             bfd_alloc (abfd,
-                        (num_locals + num_globals) * sizeof (asymbol *)));
+  amt = (num_locals + num_globals) * sizeof (asymbol *);
+  new_syms = (asymbol **) bfd_alloc (abfd, amt);
+
   if (new_syms == NULL)
     return false;
 
   for (idx = 0; idx < symcount; idx++)
     {
       asymbol *sym = syms[idx];
-      int i;
+      unsigned int i;
 
       if (!sym_is_global (abfd, sym))
        i = num_locals2++;
@@ -2195,7 +2525,7 @@ elf_map_symbols (abfd)
          && sect_syms[asect->index]->flags == 0)
        {
          asymbol *sym = sect_syms[asect->index];
-         int i;
+         unsigned int i;
 
          sym->flags = BSF_SECTION_SYM;
          if (!sym_is_global (abfd, sym))
@@ -2297,6 +2627,13 @@ _bfd_elf_compute_section_file_positions (abfd, link_info)
        return false;
     }
 
+  if (link_info == NULL || link_info->relocateable)
+    {
+      bfd_map_over_sections (abfd, set_group_contents, &failed);
+      if (failed)
+       return false;
+    }
+
   shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
   /* sh_name was set in prep_headers.  */
   shstrtab_hdr->sh_type = SHT_STRTAB;
@@ -2353,11 +2690,11 @@ make_mapping (abfd, sections, from, to, phdr)
   struct elf_segment_map *m;
   unsigned int i;
   asection **hdrpp;
+  bfd_size_type amt;
 
-  m = ((struct elf_segment_map *)
-       bfd_zalloc (abfd,
-                  (sizeof (struct elf_segment_map)
-                   + (to - from - 1) * sizeof (asection *))));
+  amt = sizeof (struct elf_segment_map);
+  amt += (to - from - 1) * sizeof (asection *);
+  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
   if (m == NULL)
     return NULL;
   m->next = NULL;
@@ -2396,6 +2733,7 @@ map_sections_to_segments (abfd)
   boolean phdr_in_segment = true;
   boolean writable;
   asection *dynsec;
+  bfd_size_type amt;
 
   if (elf_tdata (abfd)->segment_map != NULL)
     return true;
@@ -2405,8 +2743,8 @@ map_sections_to_segments (abfd)
 
   /* Select the allocated sections, and sort them.  */
 
-  sections = (asection **) bfd_malloc (bfd_count_sections (abfd)
-                                      * sizeof (asection *));
+  amt = bfd_count_sections (abfd) * sizeof (asection *);
+  sections = (asection **) bfd_malloc (amt);
   if (sections == NULL)
     goto error_return;
 
@@ -2435,8 +2773,8 @@ map_sections_to_segments (abfd)
   s = bfd_get_section_by_name (abfd, ".interp");
   if (s != NULL && (s->flags & SEC_LOAD) != 0)
     {
-      m = ((struct elf_segment_map *)
-          bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+      amt = sizeof (struct elf_segment_map);
+      m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
       if (m == NULL)
        goto error_return;
       m->next = NULL;
@@ -2449,8 +2787,8 @@ map_sections_to_segments (abfd)
       *pm = m;
       pm = &m->next;
 
-      m = ((struct elf_segment_map *)
-          bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+      amt = sizeof (struct elf_segment_map);
+      m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
       if (m == NULL)
        goto error_return;
       m->next = NULL;
@@ -2597,8 +2935,8 @@ map_sections_to_segments (abfd)
   /* If there is a .dynamic section, throw in a PT_DYNAMIC segment.  */
   if (dynsec != NULL)
     {
-      m = ((struct elf_segment_map *)
-          bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+      amt = sizeof (struct elf_segment_map);
+      m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
       if (m == NULL)
        goto error_return;
       m->next = NULL;
@@ -2620,8 +2958,8 @@ map_sections_to_segments (abfd)
       if ((s->flags & SEC_LOAD) != 0
          && strncmp (s->name, ".note", 5) == 0)
        {
-         m = ((struct elf_segment_map *)
-              bfd_zalloc (abfd, sizeof (struct elf_segment_map)));
+         amt = sizeof (struct elf_segment_map);
+         m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
          if (m == NULL)
            goto error_return;
          m->next = NULL;
@@ -2677,18 +3015,22 @@ elf_sort_sections (arg1, arg2)
   if (TOEND (sec1))
     {
       if (TOEND (sec2))
-       return sec1->target_index - sec2->target_index;
+       {
+         /* If the indicies are the same, do not return 0
+            here, but continue to try the next comparison.  */
+         if (sec1->target_index - sec2->target_index != 0)
+           return sec1->target_index - sec2->target_index;
+       }
       else
        return 1;
     }
-
-  if (TOEND (sec2))
+  else if (TOEND (sec2))
     return -1;
 
 #undef TOEND
 
-  /* Sort by size, to put zero sized sections before others at the
-     same address.  */
+  /* Sort by size, to put zero sized sections
+     before others at the same address.  */
 
   if (sec1->_raw_size < sec2->_raw_size)
     return -1;
@@ -2715,6 +3057,7 @@ assign_file_positions_for_segments (abfd)
   bfd_vma filehdr_vaddr, filehdr_paddr;
   bfd_vma phdrs_vaddr, phdrs_paddr;
   Elf_Internal_Phdr *p;
+  bfd_size_type amt;
 
   if (elf_tdata (abfd)->segment_map == NULL)
     {
@@ -2755,8 +3098,8 @@ assign_file_positions_for_segments (abfd)
   if (alloc == 0)
     alloc = count;
 
-  phdrs = ((Elf_Internal_Phdr *)
-          bfd_alloc (abfd, alloc * sizeof (Elf_Internal_Phdr)));
+  amt = alloc * sizeof (Elf_Internal_Phdr);
+  phdrs = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
   if (phdrs == NULL)
     return false;
 
@@ -3084,7 +3427,7 @@ assign_file_positions_for_segments (abfd)
   elf_tdata (abfd)->next_file_pos = off;
 
   /* Write out the program headers.  */
-  if (bfd_seek (abfd, bed->s->sizeof_ehdr, SEEK_SET) != 0
+  if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
       || bed->s->write_out_phdrs (abfd, phdrs, alloc) != 0)
     return false;
 
@@ -3329,110 +3672,22 @@ prep_headers (abfd)
     case bfd_arch_unknown:
       i_ehdrp->e_machine = EM_NONE;
       break;
-    case bfd_arch_sparc:
-      if (bfd_get_arch_size (abfd) == 64)
-       i_ehdrp->e_machine = EM_SPARCV9;
-      else
-       i_ehdrp->e_machine = EM_SPARC;
-      break;
-    case bfd_arch_i370:
-      i_ehdrp->e_machine = EM_S370;
-      break;
-    case bfd_arch_i386:
-      if (bfd_get_arch_size (abfd) == 64)
-       i_ehdrp->e_machine = EM_X86_64;
-      else
-       i_ehdrp->e_machine = EM_386;
-      break;
-    case bfd_arch_ia64:
-      i_ehdrp->e_machine = EM_IA_64;
-      break;
-    case bfd_arch_m68hc11:
-      i_ehdrp->e_machine = EM_68HC11;
-      break;
-    case bfd_arch_m68hc12:
-      i_ehdrp->e_machine = EM_68HC12;
-      break;
-    case bfd_arch_s390:
-      i_ehdrp->e_machine = EM_S390;
-      break;
-    case bfd_arch_m68k:
-      i_ehdrp->e_machine = EM_68K;
-      break;
-    case bfd_arch_m88k:
-      i_ehdrp->e_machine = EM_88K;
-      break;
-    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;
-    case bfd_arch_hppa:
-      i_ehdrp->e_machine = EM_PARISC;
-      break;
-    case bfd_arch_powerpc:
-      i_ehdrp->e_machine = EM_PPC;
-      break;
-    case bfd_arch_alpha:
-      i_ehdrp->e_machine = EM_ALPHA;
-      break;
-    case bfd_arch_sh:
-      i_ehdrp->e_machine = EM_SH;
-      break;
-    case bfd_arch_d10v:
-      i_ehdrp->e_machine = EM_CYGNUS_D10V;
-      break;
-    case bfd_arch_d30v:
-      i_ehdrp->e_machine = EM_CYGNUS_D30V;
-      break;
-    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_avr:
-      i_ehdrp->e_machine = EM_AVR;
-      break;
-    case bfd_arch_v850:
-      switch (bfd_get_mach (abfd))
-       {
-       default:
-       case 0:               i_ehdrp->e_machine = EM_CYGNUS_V850; break;
-       }
-      break;
-    case bfd_arch_arc:
-      i_ehdrp->e_machine = EM_CYGNUS_ARC;
-      break;
-    case bfd_arch_arm:
-      i_ehdrp->e_machine = EM_ARM;
-      break;
-    case bfd_arch_m32r:
-      i_ehdrp->e_machine = EM_CYGNUS_M32R;
-      break;
-    case bfd_arch_mn10200:
-      i_ehdrp->e_machine = EM_CYGNUS_MN10200;
-      break;
-    case bfd_arch_mn10300:
-      i_ehdrp->e_machine = EM_CYGNUS_MN10300;
-      break;
-    case bfd_arch_pj:
-      i_ehdrp->e_machine = EM_PJ;
-      break;
-    case bfd_arch_cris:
-      i_ehdrp->e_machine = EM_CRIS;
-      break;
-    case bfd_arch_openrisc:
-      i_ehdrp->e_machine = EM_OPENRISC;
-      break;
-      /* Also note that EM_M32, AT&T WE32100 is unknown to bfd.  */
+
+      /* There used to be a long list of cases here, each one setting
+        e_machine to the same EM_* macro #defined as ELF_MACHINE_CODE
+        in the corresponding bfd definition.  To avoid duplication,
+        the switch was removed.  Machines that need special handling
+        can generally do it in elf_backend_final_write_processing(),
+        unless they need the information earlier than the final write.
+        Such need can generally be supplied by replacing the tests for
+        e_machine with the conditions used to determine it.  */
     default:
-      i_ehdrp->e_machine = EM_NONE;
-    }
+      if (get_elf_backend_data (abfd) != NULL)
+       i_ehdrp->e_machine = get_elf_backend_data (abfd)->elf_machine_code;
+      else
+       i_ehdrp->e_machine = EM_NONE;
+      }
+
   i_ehdrp->e_version = bed->s->ev_current;
   i_ehdrp->e_ehsize = bed->s->sizeof_ehdr;
 
@@ -3540,10 +3795,10 @@ _bfd_elf_write_object_contents (abfd)
        (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
       if (i_shdrp[count]->contents)
        {
+         bfd_size_type amt = i_shdrp[count]->sh_size;
+
          if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
-             || (bfd_write (i_shdrp[count]->contents, i_shdrp[count]->sh_size,
-                            1, abfd)
-                 != i_shdrp[count]->sh_size))
+             || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
            return false;
        }
     }
@@ -3641,7 +3896,8 @@ _bfd_elf_symbol_from_bfd_symbol (abfd, asym_ptr_ptr)
        indx = asym_ptr->section->output_section->index;
       else
        indx = asym_ptr->section->index;
-      if (elf_section_syms (abfd)[indx])
+      if (indx < elf_num_section_syms (abfd)
+         && elf_section_syms (abfd)[indx] != NULL)
        asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i;
     }
 
@@ -3653,7 +3909,7 @@ _bfd_elf_symbol_from_bfd_symbol (abfd, asym_ptr_ptr)
          which is used in a relocation entry.  */
       (*_bfd_error_handler)
        (_("%s: symbol `%s' required but not present"),
-        bfd_get_filename (abfd), bfd_asymbol_name (asym_ptr));
+        bfd_archive_filename (abfd), bfd_asymbol_name (asym_ptr));
       bfd_set_error (bfd_error_no_symbols);
       return -1;
     }
@@ -3848,6 +4104,7 @@ copy_private_bfd_data (ibfd, obfd)
       bfd_vma       matching_lma;
       bfd_vma       suggested_lma;
       unsigned int  j;
+      bfd_size_type amt;
 
       if (segment->p_type == PT_NULL)
        continue;
@@ -3860,10 +4117,9 @@ copy_private_bfd_data (ibfd, obfd)
 
       /* Allocate a segment map big enough to contain all of the
         sections we have selected.  */
-      map = ((struct elf_segment_map *)
-          bfd_alloc (obfd,
-                     (sizeof (struct elf_segment_map)
-                      + ((size_t) section_count - 1) * sizeof (asection *))));
+      amt = sizeof (struct elf_segment_map);
+      amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
+      map = (struct elf_segment_map *) bfd_alloc (obfd, amt);
       if (map == NULL)
        return false;
 
@@ -3903,7 +4159,7 @@ copy_private_bfd_data (ibfd, obfd)
          if (segment->p_type == PT_LOAD)
              _bfd_error_handler
                (_("%s: warning: Empty loadable segment detected\n"),
-                bfd_get_filename (ibfd));
+                bfd_archive_filename (ibfd));
 
          map->count = 0;
          *pointer_to_map = map;
@@ -3940,8 +4196,8 @@ copy_private_bfd_data (ibfd, obfd)
         pointers that we are interested in.  As these sections get assigned
         to a segment, they are removed from this array.  */
 
-      sections = (asection **) bfd_malloc
-       (sizeof (asection *) * section_count);
+      amt = (bfd_size_type) section_count * sizeof (asection *);
+      sections = (asection **) bfd_malloc (amt);
       if (sections == NULL)
        return false;
 
@@ -4133,11 +4389,9 @@ copy_private_bfd_data (ibfd, obfd)
              /* We still have not allocated all of the sections to
                 segments.  Create a new segment here, initialise it
                 and carry on looping.  */
-             map = ((struct elf_segment_map *)
-                    bfd_alloc (obfd,
-                               (sizeof (struct elf_segment_map)
-                                + ((size_t) section_count - 1)
-                                * sizeof (asection *))));
+             amt = sizeof (struct elf_segment_map);
+             amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
+             map = (struct elf_segment_map *) bfd_alloc (obfd, amt);
              if (map == NULL)
                return false;
 
@@ -4352,6 +4606,7 @@ swap_out_syms (abfd, sttp, relocatable_p)
     Elf_Internal_Shdr *symstrtab_hdr;
     char *outbound_syms;
     int idx;
+    bfd_size_type amt;
 
     stt = _bfd_elf_stringtab_init ();
     if (stt == NULL)
@@ -4367,8 +4622,8 @@ swap_out_syms (abfd, sttp, relocatable_p)
     symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
     symstrtab_hdr->sh_type = SHT_STRTAB;
 
-    outbound_syms = bfd_alloc (abfd,
-                              (1 + symcount) * bed->s->sizeof_sym);
+    amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym;
+    outbound_syms = bfd_alloc (abfd, amt);
     if (outbound_syms == NULL)
       return false;
     symtab_hdr->contents = (PTR) outbound_syms;
@@ -4617,11 +4872,9 @@ _bfd_elf_canonicalize_reloc (abfd, section, relptr, symbols)
 {
   arelent *tblptr;
   unsigned int i;
+  struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
-  if (! get_elf_backend_data (abfd)->s->slurp_reloc_table (abfd,
-                                                          section,
-                                                          symbols,
-                                                          false))
+  if (! bed->s->slurp_reloc_table (abfd, section, symbols, false))
     return -1;
 
   tblptr = section->relocation;
@@ -4638,8 +4891,8 @@ _bfd_elf_get_symtab (abfd, alocation)
      bfd *abfd;
      asymbol **alocation;
 {
-  long symcount = get_elf_backend_data (abfd)->s->slurp_symbol_table
-    (abfd, alocation, false);
+  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  long symcount = bed->s->slurp_symbol_table (abfd, alocation, false);
 
   if (symcount >= 0)
     bfd_get_symcount (abfd) = symcount;
@@ -4651,8 +4904,8 @@ _bfd_elf_canonicalize_dynamic_symtab (abfd, alocation)
      bfd *abfd;
      asymbol **alocation;
 {
-  return get_elf_backend_data (abfd)->s->slurp_symbol_table
-    (abfd, alocation, true);
+  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  return bed->s->slurp_symbol_table (abfd, alocation, true);
 }
 
 /* Return the size required for the dynamic reloc entries.  Any
@@ -4742,6 +4995,7 @@ _bfd_elf_slurp_version_tables (abfd)
      bfd *abfd;
 {
   bfd_byte *contents = NULL;
+  bfd_size_type amt;
 
   if (elf_dynverdef (abfd) != 0)
     {
@@ -4759,7 +5013,7 @@ _bfd_elf_slurp_version_tables (abfd)
       if (contents == NULL)
        goto error_return;
       if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
-         || bfd_read ((PTR) contents, 1, hdr->sh_size, abfd) != hdr->sh_size)
+         || bfd_bread ((PTR) contents, hdr->sh_size, abfd) != hdr->sh_size)
        goto error_return;
 
       /* We know the number of entries in the section but not the maximum
@@ -4778,9 +5032,8 @@ _bfd_elf_slurp_version_tables (abfd)
                     ((bfd_byte *) everdef + iverdefmem.vd_next));
        }
 
-      elf_tdata (abfd)->verdef =
-       ((Elf_Internal_Verdef *)
-        bfd_zalloc (abfd, maxidx * sizeof (Elf_Internal_Verdef)));
+      amt = (bfd_size_type) maxidx * sizeof (Elf_Internal_Verdef);
+      elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt);
       if (elf_tdata (abfd)->verdef == NULL)
        goto error_return;
 
@@ -4801,10 +5054,8 @@ _bfd_elf_slurp_version_tables (abfd)
 
          iverdef->vd_bfd = abfd;
 
-         iverdef->vd_auxptr = ((Elf_Internal_Verdaux *)
-                               bfd_alloc (abfd,
-                                          (iverdef->vd_cnt
-                                           * sizeof (Elf_Internal_Verdaux))));
+         amt = (bfd_size_type) iverdef->vd_cnt * sizeof (Elf_Internal_Verdaux);
+         iverdef->vd_auxptr = (Elf_Internal_Verdaux *) bfd_alloc (abfd, amt);
          if (iverdef->vd_auxptr == NULL)
            goto error_return;
 
@@ -4854,9 +5105,9 @@ _bfd_elf_slurp_version_tables (abfd)
 
       hdr = &elf_tdata (abfd)->dynverref_hdr;
 
+      amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed);
       elf_tdata (abfd)->verref =
-       ((Elf_Internal_Verneed *)
-        bfd_zalloc (abfd, hdr->sh_info * sizeof (Elf_Internal_Verneed)));
+       (Elf_Internal_Verneed *) bfd_zalloc (abfd, amt);
       if (elf_tdata (abfd)->verref == NULL)
        goto error_return;
 
@@ -4866,7 +5117,7 @@ _bfd_elf_slurp_version_tables (abfd)
       if (contents == NULL)
        goto error_return;
       if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
-         || bfd_read ((PTR) contents, 1, hdr->sh_size, abfd) != hdr->sh_size)
+         || bfd_bread ((PTR) contents, hdr->sh_size, abfd) != hdr->sh_size)
        goto error_return;
 
       everneed = (Elf_External_Verneed *) contents;
@@ -4887,10 +5138,9 @@ _bfd_elf_slurp_version_tables (abfd)
          if (iverneed->vn_filename == NULL)
            goto error_return;
 
-         iverneed->vn_auxptr =
-           ((Elf_Internal_Vernaux *)
-            bfd_alloc (abfd,
-                       iverneed->vn_cnt * sizeof (Elf_Internal_Vernaux)));
+         amt = iverneed->vn_cnt;
+         amt *= sizeof (Elf_Internal_Vernaux);
+         iverneed->vn_auxptr = (Elf_Internal_Vernaux *) bfd_alloc (abfd, amt);
 
          evernaux = ((Elf_External_Vernaux *)
                      ((bfd_byte *) everneed + iverneed->vn_aux));
@@ -4940,8 +5190,9 @@ _bfd_elf_make_empty_symbol (abfd)
      bfd *abfd;
 {
   elf_symbol_type *newsym;
+  bfd_size_type amt = sizeof (elf_symbol_type);
 
-  newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof (elf_symbol_type));
+  newsym = (elf_symbol_type *) bfd_zalloc (abfd, amt);
   if (!newsym)
     return NULL;
   else
@@ -5159,6 +5410,7 @@ _bfd_elf_set_section_contents (abfd, section, location, offset, count)
      bfd_size_type count;
 {
   Elf_Internal_Shdr *hdr;
+  bfd_signed_vma pos;
 
   if (! abfd->output_has_begun
       && ! _bfd_elf_compute_section_file_positions
@@ -5166,10 +5418,9 @@ _bfd_elf_set_section_contents (abfd, section, location, offset, count)
     return false;
 
   hdr = &elf_section_data (section)->this_hdr;
-
-  if (bfd_seek (abfd, hdr->sh_offset + offset, SEEK_SET) == -1)
-    return false;
-  if (bfd_write (location, 1, count, abfd) != count)
+  pos = hdr->sh_offset + offset;
+  if (bfd_seek (abfd, pos, SEEK_SET) != 0
+      || bfd_bwrite (location, count, abfd) != count)
     return false;
 
   return true;
@@ -5288,7 +5539,7 @@ _bfd_elf_validate_reloc (abfd, areloc)
  fail:
   (*_bfd_error_handler)
     (_("%s: unsupported relocation type %s"),
-     bfd_get_filename (abfd), areloc->howto->name);
+     bfd_archive_filename (abfd), areloc->howto->name);
   bfd_set_error (bfd_error_bad_value);
   return false;
 }
@@ -5333,12 +5584,6 @@ _bfd_elf_rel_vtable_reloc_fn (abfd, re, symbol, data, is, obfd, errmsg)
 # include <sys/procfs.h>
 #endif
 
-/* Define offsetof for those systems which lack it.  */
-
-#ifndef offsetof
-# define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
-#endif
-
 /* FIXME: this is kinda wrong, but it's what gdb wants.  */
 
 static int
@@ -5387,8 +5632,8 @@ boolean
 _bfd_elfcore_make_pseudosection (abfd, name, size, filepos)
      bfd *abfd;
      char *name;
-     int size;
-     int filepos;
+     size_t size;
+     ufile_ptr filepos;
 {
   char buf[100];
   char *threaded_name;
@@ -5397,7 +5642,7 @@ _bfd_elfcore_make_pseudosection (abfd, name, size, filepos)
   /* Build the section name.  */
 
   sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
-  threaded_name = bfd_alloc (abfd, strlen (buf) + 1);
+  threaded_name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
   if (threaded_name == NULL)
     return false;
   strcpy (threaded_name, buf);
@@ -5410,10 +5655,7 @@ _bfd_elfcore_make_pseudosection (abfd, name, size, filepos)
   sect->flags = SEC_HAS_CONTENTS;
   sect->alignment_power = 2;
 
-  if (! elfcore_maybe_make_sect (abfd, name, sect))
-    return false;
-
-  return true;
+  return elfcore_maybe_make_sect (abfd, name, sect);
 }
 
 /* prstatus_t exists on:
@@ -5423,12 +5665,14 @@ _bfd_elfcore_make_pseudosection (abfd, name, size, filepos)
 */
 
 #if defined (HAVE_PRSTATUS_T)
+static boolean elfcore_grok_prstatus PARAMS ((bfd *, Elf_Internal_Note *));
+
 static boolean
 elfcore_grok_prstatus (abfd, note)
      bfd *abfd;
      Elf_Internal_Note *note;
 {
-  int raw_size;
+  size_t raw_size;
   int offset;
 
   if (note->descsz == sizeof (prstatus_t))
@@ -5484,11 +5728,8 @@ elfcore_grok_prstatus (abfd, note)
     }
 
   /* Make a ".reg/999" section and a ".reg" section.  */
-  if (! _bfd_elfcore_make_pseudosection (abfd, ".reg",
-                                        raw_size, note->descpos + offset));
-    return false;
-
-  return true;
+  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+                                         raw_size, note->descpos + offset);
 }
 #endif /* defined (HAVE_PRSTATUS_T) */
 
@@ -5499,7 +5740,8 @@ elfcore_make_note_pseudosection (abfd, name, note)
      char *name;
      Elf_Internal_Note *note;
 {
-  return _bfd_elfcore_make_pseudosection (abfd, name, note->descsz, note->descpos);
+  return _bfd_elfcore_make_pseudosection (abfd, name,
+                                         note->descsz, note->descpos);
 }
 
 /* There isn't a consistent prfpregset_t across platforms,
@@ -5544,32 +5786,33 @@ typedef psinfo32_t elfcore_psinfo32_t;
    most MAX bytes long, possibly without a terminating '\0'.
    the copy will always have a terminating '\0'.  */
 
-char*
+char *
 _bfd_elfcore_strndup (abfd, start, max)
      bfd *abfd;
      char *start;
-     int max;
+     size_t max;
 {
-  char *dup;
+  char *dups;
   char *end = memchr (start, '\0', max);
-  int len;
+  size_t len;
 
   if (end == NULL)
     len = max;
   else
     len = end - start;
 
-  dup = bfd_alloc (abfd, len + 1);
-  if (dup == NULL)
+  dups = bfd_alloc (abfd, (bfd_size_type) len + 1);
+  if (dups == NULL)
     return NULL;
 
-  memcpy (dup, start, len);
-  dup[len] = '\0';
+  memcpy (dups, start, len);
+  dups[len] = '\0';
 
-  return dup;
+  return dups;
 }
 
 #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
+static boolean elfcore_grok_psinfo PARAMS ((bfd *, Elf_Internal_Note *));
 
 static boolean
 elfcore_grok_psinfo (abfd, note)
@@ -5583,10 +5826,12 @@ elfcore_grok_psinfo (abfd, note)
       memcpy (&psinfo, note->descdata, sizeof (psinfo));
 
       elf_tdata (abfd)->core_program
-       = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, sizeof (psinfo.pr_fname));
+       = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
+                               sizeof (psinfo.pr_fname));
 
       elf_tdata (abfd)->core_command
-       = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, sizeof (psinfo.pr_psargs));
+       = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
+                               sizeof (psinfo.pr_psargs));
     }
 #if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
   else if (note->descsz == sizeof (elfcore_psinfo32_t))
@@ -5597,10 +5842,12 @@ elfcore_grok_psinfo (abfd, note)
       memcpy (&psinfo, note->descdata, sizeof (psinfo));
 
       elf_tdata (abfd)->core_program
-       = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, sizeof (psinfo.pr_fname));
+       = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
+                               sizeof (psinfo.pr_fname));
 
       elf_tdata (abfd)->core_command
-       = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, sizeof (psinfo.pr_psargs));
+       = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
+                               sizeof (psinfo.pr_psargs));
     }
 #endif
 
@@ -5690,7 +5937,7 @@ elfcore_grok_lwpstatus (abfd, note)
   /* Make a ".reg/999" section.  */
 
   sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
-  name = bfd_alloc (abfd, strlen (buf) + 1);
+  name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
   if (name == NULL)
     return false;
   strcpy (name, buf);
@@ -5719,7 +5966,7 @@ elfcore_grok_lwpstatus (abfd, note)
   /* Make a ".reg2/999" section */
 
   sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
-  name = bfd_alloc (abfd, strlen (buf) + 1);
+  name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
   if (name == NULL)
     return false;
   strcpy (name, buf);
@@ -5742,10 +5989,7 @@ elfcore_grok_lwpstatus (abfd, note)
   sect->flags = SEC_HAS_CONTENTS;
   sect->alignment_power = 2;
 
-  if (!elfcore_maybe_make_sect (abfd, ".reg2", sect))
-    return false;
-
-  return true;
+  return elfcore_maybe_make_sect (abfd, ".reg2", sect);
 }
 #endif /* defined (HAVE_LWPSTATUS_T) */
 
@@ -5777,7 +6021,7 @@ elfcore_grok_win32pstatus (abfd, note)
       /* Make a ".reg/999" section.  */
       sprintf (buf, ".reg/%d", pstatus.data.thread_info.tid);
 
-      name = bfd_alloc (abfd, strlen (buf) + 1);
+      name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
       if (name == NULL)
        return false;
 
@@ -5802,7 +6046,7 @@ elfcore_grok_win32pstatus (abfd, note)
       /* Make a ".module/xxxxxxxx" section.  */
       sprintf (buf, ".module/%08x", pstatus.data.module_info.base_address);
 
-      name = bfd_alloc (abfd, strlen (buf) + 1);
+      name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
       if (name == NULL)
        return false;
 
@@ -5890,8 +6134,8 @@ elfcore_grok_note (abfd, note)
 static boolean
 elfcore_read_notes (abfd, offset, size)
      bfd *abfd;
-     bfd_vma offset;
-     bfd_vma size;
+     file_ptr offset;
+     bfd_size_type size;
 {
   char *buf;
   char *p;
@@ -5899,14 +6143,14 @@ elfcore_read_notes (abfd, offset, size)
   if (size <= 0)
     return true;
 
-  if (bfd_seek (abfd, offset, SEEK_SET) == -1)
+  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
     return false;
 
-  buf = bfd_malloc ((size_t) size);
+  buf = bfd_malloc (size);
   if (buf == NULL)
     return false;
 
-  if (bfd_read (buf, size, 1, abfd) != size)
+  if (bfd_bread (buf, size, abfd) != size)
     {
     error:
       free (buf);
@@ -5920,12 +6164,12 @@ elfcore_read_notes (abfd, offset, size)
       Elf_External_Note *xnp = (Elf_External_Note *) p;
       Elf_Internal_Note in;
 
-      in.type = bfd_h_get_32 (abfd, (bfd_byte *) xnp->type);
+      in.type = H_GET_32 (abfd, xnp->type);
 
-      in.namesz = bfd_h_get_32 (abfd, (bfd_byte *) xnp->namesz);
+      in.namesz = H_GET_32 (abfd, xnp->namesz);
       in.namedata = xnp->name;
 
-      in.descsz = bfd_h_get_32 (abfd, (bfd_byte *) xnp->descsz);
+      in.descsz = H_GET_32 (abfd, xnp->descsz);
       in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
       in.descpos = offset + (in.descdata - buf);
 
@@ -5938,21 +6182,6 @@ elfcore_read_notes (abfd, offset, size)
   free (buf);
   return true;
 }
-
-/* FIXME: This function is now unnecessary.  Callers can just call
-   bfd_section_from_phdr directly.  */
-
-boolean
-_bfd_elfcore_section_from_phdr (abfd, phdr, sec_num)
-     bfd *abfd;
-     Elf_Internal_Phdr* phdr;
-     int sec_num;
-{
-  if (! bfd_section_from_phdr (abfd, phdr, sec_num))
-    return false;
-
-  return true;
-}
 \f
 /* Providing external access to the ELF program header table.  */
 
@@ -5970,8 +6199,7 @@ bfd_get_elf_phdr_upper_bound (abfd)
       return -1;
     }
 
-  return (elf_elfheader (abfd)->e_phnum
-         * sizeof (Elf_Internal_Phdr));
+  return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr);
 }
 
 /* Copy ABFD's program header table entries to *PHDRS.  The entries
@@ -6001,3 +6229,73 @@ bfd_get_elf_phdrs (abfd, phdrs)
 
   return num_phdrs;
 }
+
+void
+_bfd_elf_sprintf_vma (abfd, buf, value)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     char *buf;
+     bfd_vma value;
+{
+#ifdef BFD64
+  Elf_Internal_Ehdr *i_ehdrp;  /* Elf file header, internal form */
+
+  i_ehdrp = elf_elfheader (abfd);
+  if (i_ehdrp == NULL)
+    sprintf_vma (buf, value);
+  else
+    {
+      if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64)
+       {
+#if BFD_HOST_64BIT_LONG
+         sprintf (buf, "%016lx", value);
+#else
+         sprintf (buf, "%08lx%08lx", _bfd_int64_high (value),
+                  _bfd_int64_low (value));
+#endif
+       }
+      else
+       sprintf (buf, "%08lx", (unsigned long) (value & 0xffffffff));
+    }
+#else
+  sprintf_vma (buf, value);
+#endif
+}
+
+void
+_bfd_elf_fprintf_vma (abfd, stream, value)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     PTR stream;
+     bfd_vma value;
+{
+#ifdef BFD64
+  Elf_Internal_Ehdr *i_ehdrp;  /* Elf file header, internal form */
+
+  i_ehdrp = elf_elfheader (abfd);
+  if (i_ehdrp == NULL)
+    fprintf_vma ((FILE *) stream, value);
+  else
+    {
+      if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64)
+       {
+#if BFD_HOST_64BIT_LONG
+         fprintf ((FILE *) stream, "%016lx", value);
+#else
+         fprintf ((FILE *) stream, "%08lx%08lx",
+                  _bfd_int64_high (value), _bfd_int64_low (value));
+#endif
+       }
+      else
+       fprintf ((FILE *) stream, "%08lx",
+                (unsigned long) (value & 0xffffffff));
+    }
+#else
+  fprintf_vma ((FILE *) stream, value);
+#endif
+}
+
+enum elf_reloc_type_class
+_bfd_elf_reloc_type_class (rela)
+     const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED;
+{
+  return reloc_class_normal;
+}
This page took 0.081162 seconds and 4 git commands to generate.