This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Enhance support for copying and stripping Solaris and ARM binaries.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5522f910cb539905d6adfdceab208ddfa5e84557

commit 5522f910cb539905d6adfdceab208ddfa5e84557
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Apr 29 09:24:42 2016 +0100

    Enhance support for copying and stripping Solaris and ARM binaries.
    
    	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.

Diff:
---
 bfd/ChangeLog      |  25 +++++
 bfd/elf-bfd.h      |  16 ++--
 bfd/elf.c          | 268 +++++++++++++++++++++++++++++++++--------------------
 bfd/elf32-arm.c    | 108 ++++++++++++++++++++-
 bfd/elf32-i386.c   |  25 +++--
 bfd/elf32-sparc.c  |  14 +--
 bfd/elf64-x86-64.c |  14 +--
 bfd/elfxx-target.h |   6 +-
 binutils/ChangeLog |   6 ++
 binutils/readelf.c |  22 ++++-
 10 files changed, 361 insertions(+), 143 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d70dd88..f60ee03 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 6c05b55..9067dd9 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -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;
diff --git a/bfd/elf.c b/bfd/elf.c
index 69830ce..4be7d73 100644
--- 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;
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 6e27155..ba89aa6 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -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
 
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 7948fa9..4de8a2d 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -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"
 
diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c
index c045854..495d55a 100644
--- a/bfd/elf32-sparc.c
+++ b/bfd/elf32-sparc.c
@@ -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
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 02fcb22..8a5ce75 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -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.  */
 
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index fde34b7..c1bbadc 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -686,8 +686,8 @@
 #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,
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 7a19cc7..7eea2c0 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index cf91755..b6454d3 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -3689,6 +3689,23 @@ get_tic6x_segment_type (unsigned long type)
 }
 
 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)
 {
   static char buff[32];
@@ -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;
 	    }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]