Enhance support for copying and stripping Solaris and ARM binaries.
authorNick Clifton <nickc@redhat.com>
Fri, 29 Apr 2016 08:24:42 +0000 (09:24 +0100)
committerNick Clifton <nickc@redhat.com>
Fri, 29 Apr 2016 08:24:42 +0000 (09:24 +0100)
PR 19938
bfd * elf-bfd.h (struct elf_backend_data): Rename
elf_backend_set_special_section_info_and_link to
elf_backend_copy_special_section_fields.
* elfxx-target.h: Likewise.
* elf.c (section_match): Ignore the SHF_INFO_LINK flag when
comparing section flags.
(copy_special_section_fields): New function.
(_bfd_elf_copy_private_bfd_data): Copy the EI_ABIVERSION field.
Perform two scans over special sections.  The first one looks for
a direct mapping between the output section and an input section.
The second scan looks for a possible match based upon section
characteristics.
* elf32-arm.c (elf32_arm_copy_special_section_fields): New
function.  Handle setting the sh_link field of SHT_ARM_EXIDX
sections.
* elf32-i386.c (elf32_i386_set_special_info_link): Rename to
elf32_i386_copy_solaris_special_section_fields.
* elf32-sparc.c (elf32_sparc_set_special_section_info_link):
Rename to elf32_sparc_copy_solaris_special_section_fields.
* elf64-x86-64.c (elf64_x86_64_set_special_info_link): Rename to
elf64_x86_64_copy_solaris_special_section_fields.

binutils* readelf.c (get_solaris_segment_type): New function.
(get_segment_type): Call it.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c
bfd/elf32-arm.c
bfd/elf32-i386.c
bfd/elf32-sparc.c
bfd/elf64-x86-64.c
bfd/elfxx-target.h
binutils/ChangeLog
binutils/readelf.c

index d70dd881e7c42c5d783557a2c46580d1558d6c60..f60ee034c387d2b77bfc2cf14c7924bdaa7d9cc7 100644 (file)
@@ -1,3 +1,28 @@
+2016-04-29  Nick Clifton  <nickc@redhat.com>
+
+       PR 19938
+       * elf-bfd.h (struct elf_backend_data): Rename
+       elf_backend_set_special_section_info_and_link to
+       elf_backend_copy_special_section_fields.
+       * elfxx-target.h: Likewise.
+       * elf.c (section_match): Ignore the SHF_INFO_LINK flag when
+       comparing section flags.
+       (copy_special_section_fields): New function.
+       (_bfd_elf_copy_private_bfd_data): Copy the EI_ABIVERSION field.
+       Perform two scans over special sections.  The first one looks for
+       a direct mapping between the output section and an input section.
+       The second scan looks for a possible match based upon section
+       characteristics.
+       * elf32-arm.c (elf32_arm_copy_special_section_fields): New
+       function.  Handle setting the sh_link field of SHT_ARM_EXIDX
+       sections.
+       * elf32-i386.c (elf32_i386_set_special_info_link): Rename to
+       elf32_i386_copy_solaris_special_section_fields.
+       * elf32-sparc.c (elf32_sparc_set_special_section_info_link):
+       Rename to elf32_sparc_copy_solaris_special_section_fields.
+       * elf64-x86-64.c (elf64_x86_64_set_special_info_link): Rename to
+       elf64_x86_64_copy_solaris_special_section_fields.
+
 2016-04-28  Nick Clifton  <nickc@redhat.com>
 
        * po/zh_CN.po: Updated Chinese (simplified) translation.
index 6c05b55b641f554a11f825a4219dbba9860aa420..9067dd9aea174739300af7b8076b558267e27b94 100644 (file)
@@ -1300,13 +1300,15 @@ struct elf_backend_data
   /* Return the section which RELOC_SEC applies to.  */
   asection *(*get_reloc_section) (asection *reloc_sec);
 
-  /* Called when setting the sh_link and sh_info fields of a section with a
-     type >= SHT_LOOS.  Returns TRUE if these fields were initialised in
-     OHEADER, FALSE otherwise.  IHEADER is the best guess matching section
-     from the input bfd IBFD.  */
-  bfd_boolean (*elf_backend_set_special_section_info_and_link)
-    (const bfd *ibfd, bfd *obfd, const Elf_Internal_Shdr *iheader,
-     Elf_Internal_Shdr *oheader);
+  /* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which
+     has a type >= SHT_LOOS.  Returns TRUE if the fields were initialised,
+     FALSE otherwise.  Can be called multiple times for a given section,
+     until it returns TRUE.  Most of the times it is called ISECTION will be
+     set to an input section that might be associated with the output section.
+     The last time that it is called, ISECTION will be set to NULL.  */
+  bfd_boolean (*elf_backend_copy_special_section_fields)
+    (const bfd *ibfd, bfd *obfd, const Elf_Internal_Shdr *isection,
+     Elf_Internal_Shdr *osection);
                
   /* Used to handle bad SHF_LINK_ORDER input.  */
   bfd_error_handler_type link_order_error_handler;
index 69830ce0b3a2e567dcb052ba19a011d91af67c93..4be7d73973925082a997a5994ecad9a31a53913b 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1218,11 +1218,13 @@ bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
    should be the same.  */
 
 static bfd_boolean
-section_match (Elf_Internal_Shdr * a, Elf_Internal_Shdr * b)
+section_match (const Elf_Internal_Shdr * a,
+              const Elf_Internal_Shdr * b)
 {
   return
     a->sh_type         == b->sh_type
-    && a->sh_flags     == b->sh_flags
+    && (a->sh_flags & ~ SHF_INFO_LINK)
+    == (b->sh_flags & ~ SHF_INFO_LINK)
     && a->sh_addralign == b->sh_addralign
     && a->sh_size      == b->sh_size
     && a->sh_entsize   == b->sh_entsize
@@ -1236,7 +1238,7 @@ section_match (Elf_Internal_Shdr * a, Elf_Internal_Shdr * b)
    to be the correct section.  */
 
 static unsigned int
-find_link (bfd * obfd, Elf_Internal_Shdr * iheader, unsigned int hint)
+find_link (const bfd * obfd, const Elf_Internal_Shdr * iheader, const unsigned int hint)
 {
   Elf_Internal_Shdr ** oheaders = elf_elfsections (obfd);
   unsigned int i;
@@ -1257,14 +1259,110 @@ find_link (bfd * obfd, Elf_Internal_Shdr * iheader, unsigned int hint)
   return SHN_UNDEF;
 }
 
+/* PR 19938: Attempt to set the ELF section header fields of an OS or
+   Processor specific section, based upon a matching input section.
+   Returns TRUE upon success, FALSE otherwise.  */
+   
+static bfd_boolean
+copy_special_section_fields (const bfd *ibfd,
+                            bfd *obfd,
+                            const Elf_Internal_Shdr *iheader,
+                            Elf_Internal_Shdr *oheader,
+                            const unsigned int secnum)
+{
+  const struct elf_backend_data *bed = get_elf_backend_data (obfd);
+  const Elf_Internal_Shdr **iheaders = (const Elf_Internal_Shdr **) elf_elfsections (ibfd);
+  bfd_boolean changed = FALSE;
+  unsigned int sh_link;
+
+  if (oheader->sh_type == SHT_NOBITS)
+    {
+      /* This is a feature for objcopy --only-keep-debug:
+        When a section's type is changed to NOBITS, we preserve
+        the sh_link and sh_info fields so that they can be
+        matched up with the original.
+
+        Note: Strictly speaking these assignments are wrong.
+        The sh_link and sh_info fields should point to the
+        relevent sections in the output BFD, which may not be in
+        the same location as they were in the input BFD.  But
+        the whole point of this action is to preserve the
+        original values of the sh_link and sh_info fields, so
+        that they can be matched up with the section headers in
+        the original file.  So strictly speaking we may be
+        creating an invalid ELF file, but it is only for a file
+        that just contains debug info and only for sections
+        without any contents.  */
+      if (oheader->sh_link == 0)
+       oheader->sh_link = iheader->sh_link;
+      if (oheader->sh_info == 0)
+       oheader->sh_info = iheader->sh_info;
+      return TRUE;
+    }
+
+  /* Allow the target a chance to decide how these fields should be set.  */
+  if (bed->elf_backend_copy_special_section_fields != NULL
+      && bed->elf_backend_copy_special_section_fields
+      (ibfd, obfd, iheader, oheader))
+    return TRUE;
+
+  /* We have an iheader which might match oheader, and which has non-zero
+     sh_info and/or sh_link fields.  Attempt to follow those links and find
+     the section in the output bfd which corresponds to the linked section
+     in the input bfd.  */
+  if (iheader->sh_link != SHN_UNDEF)
+    {
+      sh_link = find_link (obfd, iheaders[iheader->sh_link], iheader->sh_link);
+      if (sh_link != SHN_UNDEF)
+       {
+         oheader->sh_link = sh_link;
+         changed = TRUE;
+       }
+      else
+       /* FIXME: Should we install iheader->sh_link
+          if we could not find a match ?  */
+       (* _bfd_error_handler)
+         (_("%B: Failed to find link section for section %d"), obfd, secnum);
+    }
+
+  if (iheader->sh_info)
+    {
+      /* The sh_info field can hold arbitrary information, but if the
+        SHF_LINK_INFO flag is set then it should be interpreted as a
+        section index.  */
+      if (iheader->sh_flags & SHF_INFO_LINK)
+       {
+         sh_link = find_link (obfd, iheaders[iheader->sh_info],
+                              iheader->sh_info);
+         if (sh_link != SHN_UNDEF)
+           oheader->sh_flags |= SHF_INFO_LINK;
+       }
+      else
+       /* No idea what it means - just copy it.  */
+       sh_link = iheader->sh_info;
+
+      if (sh_link != SHN_UNDEF)
+       {
+         oheader->sh_info = sh_link;
+         changed = TRUE;
+       }
+      else
+       (* _bfd_error_handler)
+         (_("%B: Failed to find info section for section %d"), obfd, secnum);
+    }
+
+  return changed;
+}
+  
 /* Copy the program header and other data from one object module to
    another.  */
 
 bfd_boolean
 _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
-  Elf_Internal_Shdr ** iheaders = elf_elfsections (ibfd);
-  Elf_Internal_Shdr ** oheaders = elf_elfsections (obfd);
+  const Elf_Internal_Shdr **iheaders = (const Elf_Internal_Shdr **) elf_elfsections (ibfd);
+  Elf_Internal_Shdr **oheaders = elf_elfsections (obfd);
+  const struct elf_backend_data *bed;
   unsigned int i;
 
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
@@ -1283,39 +1381,84 @@ _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
   elf_elfheader (obfd)->e_ident[EI_OSABI] =
     elf_elfheader (ibfd)->e_ident[EI_OSABI];
 
+  /* If set, copy the EI_ABIVERSION field.  */
+  if (elf_elfheader (ibfd)->e_ident[EI_ABIVERSION])
+    elf_elfheader (obfd)->e_ident[EI_ABIVERSION]
+      = elf_elfheader (ibfd)->e_ident[EI_ABIVERSION];
+  
   /* Copy object attributes.  */
   _bfd_elf_copy_obj_attributes (ibfd, obfd);
 
   if (iheaders == NULL || oheaders == NULL)
     return TRUE;
 
-  /* Possibly copy the sh_info and sh_link fields.  */
+  bed = get_elf_backend_data (obfd);
+
+  /* Possibly copy other fields in the section header.  */
   for (i = 1; i < elf_numsections (obfd); i++)
     {
       unsigned int j;
       Elf_Internal_Shdr * oheader = oheaders[i];
 
+      /* Ignore ordinary sections.  SHT_NOBITS sections are considered however
+        because of a special case need for generating separate debug info
+        files.  See below for more details.  */
       if (oheader == NULL
          || (oheader->sh_type != SHT_NOBITS
-             && oheader->sh_type < SHT_LOOS)
-         || oheader->sh_size == 0
+             && oheader->sh_type < SHT_LOOS))
+       continue;
+
+      /* Ignore empty sections, and sections whose
+        fields have already been initialised.  */
+      if (oheader->sh_size == 0
          || (oheader->sh_info != 0 && oheader->sh_link != 0))
        continue;
 
       /* Scan for the matching section in the input bfd.
-        FIXME: We could use something better than a linear scan here.
+        First we try for a direct mapping between the input and output sections.  */
+      for (j = 1; j < elf_numsections (ibfd); j++)
+       {
+         const Elf_Internal_Shdr * iheader = iheaders[j];
+
+         if (iheader == NULL)
+           continue;
+
+         if (oheader->bfd_section != NULL
+             && iheader->bfd_section != NULL
+             && iheader->bfd_section->output_section != NULL
+             && iheader->bfd_section->output_section == oheader->bfd_section)
+           {
+             /* We have found a connection from the input section to the
+                output section.  Attempt to copy the header fields.  If
+                this fails then do not try any further sections - there
+                should only be a one-to-one mapping between input and output. */
+             if (! copy_special_section_fields (ibfd, obfd, iheader, oheader, i))
+               j = elf_numsections (ibfd);
+             break;
+           }
+       }
+
+      if (j < elf_numsections (ibfd))
+       continue;
+
+      /* That failed.  So try to deduce the corresponding input section.
         Unfortunately we cannot compare names as the output string table
         is empty, so instead we check size, address and type.  */
       for (j = 1; j < elf_numsections (ibfd); j++)
        {
-         Elf_Internal_Shdr * iheader = iheaders[j];
+         const Elf_Internal_Shdr * iheader = iheaders[j];
+
+         if (iheader == NULL)
+           continue;
 
-         /* Since --only-keep-debug turns all non-debug sections into
+         /* Try matching fields in the input section's header.
+            Since --only-keep-debug turns all non-debug sections into
             SHT_NOBITS sections, the output SHT_NOBITS type matches any
             input type.  */
          if ((oheader->sh_type == SHT_NOBITS
               || iheader->sh_type == oheader->sh_type)
-             && iheader->sh_flags == oheader->sh_flags
+             && (iheader->sh_flags & ~ SHF_INFO_LINK)
+             == (oheader->sh_flags & ~ SHF_INFO_LINK)
              && iheader->sh_addralign == oheader->sh_addralign
              && iheader->sh_entsize == oheader->sh_entsize
              && iheader->sh_size == oheader->sh_size
@@ -1323,99 +1466,18 @@ _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
              && (iheader->sh_info != oheader->sh_info
                  || iheader->sh_link != oheader->sh_link))
            {
-             /* PR 19938: Attempt to preserve the sh_link and sh_info fields
-                of OS and Processor specific sections.  We try harder for
-                these sections, because this is not just about matching
-                stripped binaries to their originals.  */
-             if (oheader->sh_type >= SHT_LOOS)
-               {
-                 const struct elf_backend_data *bed = get_elf_backend_data (obfd);
-                 bfd_boolean changed = FALSE;
-                 unsigned int sh_link;
-
-                 /* Allow the target a chance to decide how these fields should
-                    be set.  */
-                 if (bed->elf_backend_set_special_section_info_and_link != NULL
-                     && bed->elf_backend_set_special_section_info_and_link
-                     (ibfd, obfd, iheader, oheader))
-                   break;
-
-                 /* We have iheader which matches oheader, but which has
-                    non-zero sh_info and/or sh_link fields.  Attempt to
-                    follow those links and find the section in the output
-                    bfd which corresponds to the linked section in the input
-                    bfd.  */
-                 if (iheader->sh_link != SHN_UNDEF)
-                   {
-                     sh_link = find_link (obfd,
-                                          iheaders[iheader->sh_link],
-                                          iheader->sh_link);
-                     if (sh_link != SHN_UNDEF)
-                       {
-                         oheader->sh_link = sh_link;
-                         changed = TRUE;
-                       }
-                     else
-                       /* FIXME: Should we install iheader->sh_link
-                          if we could not find a match ?  */
-                       (* _bfd_error_handler)
-                         (_("%B: Failed to find link section for section %d"),
-                          obfd, i);
-                   }
-
-                 if (iheader->sh_info)
-                   {
-                     /* The sh_info field can hold arbitrary information,
-                        but if the SHF_LINK_INFO flag is set then it
-                        should be interpreted as a section index.  */
-                     if (iheader->sh_flags & SHF_INFO_LINK)
-                       sh_link = find_link (obfd,
-                                            iheaders[iheader->sh_info],
-                                            iheader->sh_info);
-                     else
-                       /* No idea what it means - just copy it.  */
-                       sh_link = iheader->sh_info;
-                         
-                     if (sh_link != SHN_UNDEF)
-                       {
-                         oheader->sh_info = sh_link;
-                         changed = TRUE;
-                       }
-                     else
-                       (* _bfd_error_handler)
-                         (_("%B: Failed to find info section for section %d"),
-                          obfd, i);
-                   }
-
-                 if (changed)
-                   break;
-               }
-             else
-               {
-                 /* This is an feature for objcopy --only-keep-debug:
-                    When a section's type is changed to NOBITS, we preserve
-                    the sh_link and sh_info fields so that they can be
-                    matched up with the original.
-
-                    Note: Strictly speaking these assignments are wrong.
-                    The sh_link and sh_info fields should point to the
-                    relevent sections in the output BFD, which may not be in
-                    the same location as they were in the input BFD.  But
-                    the whole point of this action is to preserve the
-                    original values of the sh_link and sh_info fields, so
-                    that they can be matched up with the section headers in
-                    the original file.  So strictly speaking we may be
-                    creating an invalid ELF file, but it is only for a file
-                    that just contains debug info and only for sections
-                    without any contents.  */
-                 if (oheader->sh_link == 0)
-                   oheader->sh_link = iheader->sh_link;
-                 if (oheader->sh_info == 0)
-                   oheader->sh_info = iheader->sh_info;
-                 break;
-               }
+             if (copy_special_section_fields (ibfd, obfd, iheader, oheader, i))
+               break;
            }
        }
+
+      if (j == elf_numsections (ibfd) && oheader->sh_type >= SHT_LOOS)
+       {
+         /* Final attempt.  Call the backend copy function
+            with a NULL input section.  */
+         if (bed->elf_backend_copy_special_section_fields != NULL)
+           bed->elf_backend_copy_special_section_fields (ibfd, obfd, NULL, oheader);
+       }
     }
 
   return TRUE;
index 6e27155d5d30fdb5127c75448c722c7b0a03f4bb..ba89aa6c2621480e36ed219a845dee822b926fb5 100644 (file)
@@ -14112,11 +14112,15 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
   s = bfd_get_linker_section (dynobj, ".dynbss");
   BFD_ASSERT (s != NULL);
 
-  /* We must generate a R_ARM_COPY reloc to tell the dynamic linker to
-     copy the initial value out of the dynamic object and into the
-     runtime process image.  We need to remember the offset into the
+  /* If allowed, we must generate a R_ARM_COPY reloc to tell the dynamic
+     linker to copy the initial value out of the dynamic object and into
+     the runtime process image.  We need to remember the offset into the
      .rel(a).bss section we are going to use.  */
-  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+  if (info->nocopyreloc == 0
+      && (h->root.u.def.section->flags & SEC_ALLOC) != 0
+      /* PR 16177: A copy is only needed if the input section is readonly.  */
+      && (h->root.u.def.section->flags & SEC_READONLY) == 0
+      && h->size != 0)
     {
       asection *srel;
 
@@ -17873,6 +17877,100 @@ elf32_arm_count_additional_relocs (asection *sec)
   return arm_data->additional_reloc_count;
 }
 
+/* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which
+   has a type >= SHT_LOOS.  Returns TRUE if these fields were initialised 
+   FALSE otherwise.  ISECTION is the best guess matching section from the
+   input bfd IBFD, but it might be NULL.  */
+
+static bfd_boolean
+elf32_arm_copy_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
+                                      bfd *obfd ATTRIBUTE_UNUSED,
+                                      const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
+                                      Elf_Internal_Shdr *osection)
+{
+  switch (osection->sh_type)
+    {
+    case SHT_ARM_EXIDX:
+      {
+       Elf_Internal_Shdr **oheaders = elf_elfsections (obfd);
+       Elf_Internal_Shdr **iheaders = elf_elfsections (ibfd);
+       unsigned i = 0;
+
+       osection->sh_flags = SHF_ALLOC | SHF_LINK_ORDER;
+       osection->sh_info = 0;
+
+       /* The sh_link field must be set to the text section associated with
+          this index section.  Unfortunately the ARM EHABI does not specify
+          exactly how to determine this association.  Our caller does try
+          to match up OSECTION with its corresponding input section however
+          so that is a good first guess.  */
+       if (isection != NULL
+           && osection->bfd_section != NULL
+           && isection->bfd_section != NULL
+           && isection->bfd_section->output_section != NULL
+           && isection->bfd_section->output_section == osection->bfd_section
+           && iheaders != NULL
+           && isection->sh_link > 0
+           && isection->sh_link < elf_numsections (ibfd)
+           && iheaders[isection->sh_link]->bfd_section != NULL
+           && iheaders[isection->sh_link]->bfd_section->output_section != NULL
+           )
+         {
+           for (i = elf_numsections (obfd); i-- > 0;)
+             if (oheaders[i]->bfd_section
+                 == iheaders[isection->sh_link]->bfd_section->output_section)
+               break;
+         }
+           
+       if (i == 0)
+         {
+           /* Failing that we have to find a matching section ourselves.  If
+              we had the output section name available we could compare that
+              with input section names.  Unfortunately we don't.  So instead
+              we use a simple heuristic and look for the nearest executable
+              section before this one.  */
+           for (i = elf_numsections (obfd); i-- > 0;)
+             if (oheaders[i] == osection)
+               break;
+           if (i == 0)
+             break;
+
+           while (i-- > 0)
+             if (oheaders[i]->sh_type == SHT_PROGBITS
+                 && (oheaders[i]->sh_flags & (SHF_ALLOC | SHF_EXECINSTR))
+                 == (SHF_ALLOC | SHF_EXECINSTR))
+               break;
+         }
+
+       if (i)
+         {
+           osection->sh_link = i;
+           /* If the text section was part of a group
+              then the index section should be too.  */
+           if (oheaders[i]->sh_flags & SHF_GROUP)
+             osection->sh_flags |= SHF_GROUP;
+           return TRUE;
+         }
+      }
+      break;
+
+    case SHT_ARM_PREEMPTMAP:
+      osection->sh_flags = SHF_ALLOC;
+      break;
+
+    case SHT_ARM_ATTRIBUTES:
+    case SHT_ARM_DEBUGOVERLAY:
+    case SHT_ARM_OVERLAYSECTION:
+    default:
+      break;
+    }
+
+  return FALSE;
+}
+
+#undef  elf_backend_copy_special_section_fields
+#define elf_backend_copy_special_section_fields elf32_arm_copy_special_section_fields
+
 #define ELF_ARCH                       bfd_arch_arm
 #define ELF_TARGET_ID                  ARM_ELF_DATA
 #define ELF_MACHINE_CODE               EM_ARM
@@ -18035,6 +18133,7 @@ elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt,
 #undef bfd_elf32_get_synthetic_symtab
 #undef  elf_backend_plt_sym_val
 #define elf_backend_plt_sym_val                        elf32_arm_nacl_plt_sym_val
+#undef  elf_backend_copy_special_section_fields
 
 #undef ELF_MINPAGESIZE
 #undef ELF_COMMONPAGESIZE
@@ -18454,7 +18553,6 @@ elf32_arm_symbian_plt_sym_val (bfd_vma i, const asection *plt,
   return plt->vma + 4 * ARRAY_SIZE (elf32_arm_symbian_plt_entry) * i;
 }
 
-
 #undef  elf32_bed
 #define elf32_bed elf32_arm_symbian_bed
 
index 7948fa99907b105af8fcad1005f7f8f18760e38d..4de8a2df8df2e74d6dc0aaa745e2512c4817164b 100644 (file)
@@ -5905,16 +5905,22 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
 #undef  elf_backend_strtab_flags
 #define elf_backend_strtab_flags       SHF_STRINGS
 
+/* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which
+   has a type >= SHT_LOOS.  Returns TRUE if these fields were initialised 
+   FALSE otherwise.  ISECTION is the best guess matching section from the
+   input bfd IBFD, but it might be NULL.  */
+
 static bfd_boolean
-elf32_i386_set_special_info_link (const bfd *ibfd ATTRIBUTE_UNUSED,
-                                 bfd *obfd ATTRIBUTE_UNUSED,
-                                 const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
-                                 Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED)
+elf32_i386_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
+                                               bfd *obfd ATTRIBUTE_UNUSED,
+                                               const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
+                                               Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED)
 {
   /* PR 19938: FIXME: Need to add code for setting the sh_info
-     and sh_link fields of Solaris specific section types.
+     and sh_link fields of Solaris specific section types.  */
+  return FALSE;
 
-     Based upon Oracle Solaris 11.3 Linkers and Libraries Guide, Ch. 13,
+  /* Based upon Oracle Solaris 11.3 Linkers and Libraries Guide, Ch. 13,
      Object File Format, Table 13-9  ELF sh_link and sh_info Interpretation:
 
 http://docs.oracle.com/cd/E53394_01/html/E54813/chapter6-94076.html#scrolltoc
@@ -5974,11 +5980,10 @@ SHT_SUNW_verneed     The section header index of    The number of version
 
 SHT_SUNW_versym      The section header index of    0
  [0x6fffffff]        the associated symbol table.  */
-  return FALSE;
 }
 
-#undef  elf_backend_set_special_section_info_and_link
-#define elf_backend_set_special_section_info_and_link elf32_i386_set_special_info_link
+#undef  elf_backend_copy_special_section_fields
+#define elf_backend_copy_special_section_fields elf32_i386_copy_solaris_special_section_fields
 
 #include "elf32-target.h"
 
@@ -6016,7 +6021,7 @@ elf32_iamcu_elf_object_p (bfd *abfd)
 #define elf_backend_want_plt_sym           0
 
 #undef  elf_backend_strtab_flags
-#undef  elf_backend_set_special_section_info_and_link
+#undef  elf_backend_copy_special_section_fields
 
 #include "elf32-target.h"
 
index c045854f89a22f3ee89568d5da6f2302879df8c1..495d55a199a87e21070e133ac8ba6e16f856d663 100644 (file)
@@ -265,18 +265,18 @@ elf32_sparc_add_symbol_hook (bfd * abfd,
 #define elf_backend_strtab_flags       SHF_STRINGS
 
 static bfd_boolean
-elf32_sparc_set_special_info_link (const bfd *ibfd ATTRIBUTE_UNUSED,
-                                  bfd *obfd ATTRIBUTE_UNUSED,
-                                  const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
-                                  Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED)
+elf32_sparc_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
+                                                bfd *obfd ATTRIBUTE_UNUSED,
+                                                const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
+                                                Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED)
 {
   /* PR 19938: FIXME: Need to add code for setting the sh_info
      and sh_link fields of Solaris specific section types.  */
   return FALSE;
 }
 
-#undef  elf_backend_set_special_section_info_and_link
-#define elf_backend_set_special_section_info_and_link elf32_sparc_set_special_info_link
+#undef  elf_backend_copy_special_section_fields
+#define elf_backend_copy_special_section_fields elf32_sparc_copy_solaris_special_section_fields
 
 #include "elf32-target.h"
 
@@ -341,7 +341,7 @@ elf32_sparc_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
   elf32_sparc_vxworks_final_write_processing
 #undef  elf_backend_static_tls_alignment
 #undef  elf_backend_strtab_flags
-#undef  elf_backend_set_special_section_info_and_link
+#undef  elf_backend_copy_special_section_fields
 
 #undef  elf32_bed
 #define elf32_bed                              sparc_elf_vxworks_bed
index 02fcb220b9119be1d75f62b58676ca6be6ade3c5..8a5ce75091468ecdb2f08609d1cf68a3a160047c 100644 (file)
@@ -6552,18 +6552,18 @@ static const struct bfd_elf_special_section
 #define elf_backend_strtab_flags       SHF_STRINGS
 
 static bfd_boolean
-elf64_x86_64_set_special_info_link (const bfd *ibfd ATTRIBUTE_UNUSED,
-                                   bfd *obfd ATTRIBUTE_UNUSED,
-                                   const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
-                                   Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED)
+elf64_x86_64_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
+                                                 bfd *obfd ATTRIBUTE_UNUSED,
+                                                 const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
+                                                 Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED)
 {
   /* PR 19938: FIXME: Need to add code for setting the sh_info
      and sh_link fields of Solaris specific section types.  */
   return FALSE;
 }
 
-#undef  elf_backend_set_special_section_info_and_link
-#define elf_backend_set_special_section_info_and_link elf64_x86_64_set_special_info_link
+#undef  elf_backend_copy_special_section_fields
+#define elf_backend_copy_special_section_fields elf64_x86_64_copy_solaris_special_section_fields
 
 #include "elf64-target.h"
 
@@ -6597,7 +6597,7 @@ elf64_x86_64_nacl_elf_object_p (bfd *abfd)
 #undef elf_backend_want_plt_sym
 #define elf_backend_want_plt_sym       0
 #undef  elf_backend_strtab_flags
-#undef  elf_backend_set_special_section_info_and_link
+#undef  elf_backend_copy_special_section_fields
 
 /* NaCl uses substantially different PLT entries for the same effects.  */
 
index fde34b7d2928b375dd9c75d850a132b24f3c23dc..c1bbadce6ddc39f78da38acce84a4caa49922e8c 100644 (file)
 #define elf_backend_get_reloc_section _bfd_elf_get_reloc_section
 #endif
 
-#ifndef elf_backend_set_special_section_info_and_link
-#define elf_backend_set_special_section_info_and_link NULL
+#ifndef elf_backend_copy_special_section_fields
+#define elf_backend_copy_special_section_fields NULL
 #endif
 
 #ifndef elf_backend_compact_eh_encoding
@@ -797,7 +797,7 @@ static struct elf_backend_data elfNN_bed =
   elf_backend_is_function_type,
   elf_backend_maybe_function_sym,
   elf_backend_get_reloc_section,
-  elf_backend_set_special_section_info_and_link,
+  elf_backend_copy_special_section_fields,
   elf_backend_link_order_error_handler,
   elf_backend_relplt_name,
   ELF_MACHINE_ALT1,
index 7a19cc7da3f561c1baeb7c8fa27ad16f8e617ebf..7eea2c05d9f9004ec8571d021f2de98822389a4c 100644 (file)
@@ -1,3 +1,9 @@
+2016-04-29  Nick Clifton  <nickc@redhat.com>
+
+       PR 19938
+       * readelf.c (get_solaris_segment_type): New function.
+       (get_segment_type): Call it.
+
 2016-04-28  Nick Clifton  <nickc@redhat.com>
 
        * po/zh_CN.po: Updated Chinese (simplified) translation.
index cf917556c0923c234f67526af4aa6d0efa3bc35c..b6454d353279dc57745cd5a2d68b5f3f69f8e17c 100644 (file)
@@ -3688,6 +3688,23 @@ get_tic6x_segment_type (unsigned long type)
   return NULL;
 }
 
+static const char *
+get_solaris_segment_type (unsigned long type)
+{
+  switch (type)
+    {
+    case 0x6464e550: return "PT_SUNW_UNWIND";
+    case 0x6474e550: return "PT_SUNW_EH_FRAME";
+    case 0x6ffffff7: return "PT_LOSUNW";
+    case 0x6ffffffa: return "PT_SUNWBSS";
+    case 0x6ffffffb: return "PT_SUNWSTACK";
+    case 0x6ffffffc: return "PT_SUNWDTRACE";
+    case 0x6ffffffd: return "PT_SUNWCAP";
+    case 0x6fffffff: return "PT_HISUNW";
+    default: return NULL;
+    }
+}
+
 static const char *
 get_segment_type (unsigned long p_type)
 {
@@ -3758,7 +3775,10 @@ get_segment_type (unsigned long p_type)
              result = get_ia64_segment_type (p_type);
              break;
            default:
-             result = NULL;
+             if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
+               result = get_solaris_segment_type (p_type);
+             else
+               result = NULL;
              break;
            }