This is the mail archive of the binutils@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]

PATCH: PR ld/1487: ELF input section may not be handled properly


On Wed, Oct 19, 2005 at 11:24:09PM +0200, Hans-Peter Nilsson wrote:
> Your new test seems to fail for cris-axis-elf but I'd guess the
> failure is not target-specific.  My autotester binutils.log
> says:
> 

If an ELF input section has a type, which isn't sepecial to bfd, we
don't handle it properly. This patch sets the output ELF section type
the same as the input. I also simplify the SHF_GROUP/SHF_LINK_ORDER
handling.

One side effect is that .IA_64.unwind now has the proper type so that
_bfd_elf_link_omit_section_dynsym will remove it from the .dynsym
section.


H.J.
-----
bfd/

2005-10-20  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/1487
	* elf-bfd.h (_bfd_generic_init_private_section_data): New.
	(_bfd_elf_init_private_section_data): New.

	* elf.c (elf_fake_sections): Don't set SHF_GROUP for
	relocatable link.
	(bfd_elf_set_group_contents): Don't handle relocatable link
	specially.
	(assign_section_numbers): If it isn't called by assembler,
	use the output section of elf_linked_to_section for
	SHF_LINK_ORDER.
	(_bfd_elf_init_private_section_data): New.
	(_bfd_elf_copy_private_section_data): Call it.

	* libbfd-in.h (_bfd_generic_init_private_section_data): New.

	* libbfd.c (_bfd_generic_init_private_section_data): New.

	* targets.c (BFD_JUMP_TABLE_COPY): Add
	_bfd_generic_init_private_section_data.
	(bfd_init_private_section_data): Likewise.

	* bfd-in2.h: Regenerated.
	* libbfd.h: Likewise.

ld/

2005-10-20  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/1487
	* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Call
	bfd_match_sections_by_type to match section types.

	* ldlang.c (init_os): Take the input section. Call
	bfd_init_private_section_data if the input section isn't NULL.
	(exp_init_os): Pass NULL to init_os.
	(map_input_to_output_sections): Likewise.
	(lang_add_section): Pass the input section to init_os.

ld/testsuite/

2005-10-20  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/1487
	* ld-ia64/tlspic.rd: Updated.

--- binutils/bfd/elf-bfd.h.copy	2005-10-17 09:40:29.000000000 -0700
+++ binutils/bfd/elf-bfd.h	2005-10-20 10:12:36.000000000 -0700
@@ -1492,6 +1492,10 @@ extern bfd_boolean _bfd_elf_copy_private
   (bfd *, bfd *);
 extern bfd_boolean _bfd_elf_copy_private_symbol_data
   (bfd *, asymbol *, bfd *, asymbol *);
+#define _bfd_generic_init_private_section_data \
+  _bfd_elf_init_private_section_data
+extern bfd_boolean _bfd_elf_init_private_section_data
+  (bfd *, asection *, bfd *, asection *, struct bfd_link_info *);
 extern bfd_boolean _bfd_elf_copy_private_section_data
   (bfd *, asection *, bfd *, asection *);
 extern bfd_boolean _bfd_elf_write_object_contents
--- binutils/bfd/elf.c.copy	2005-10-15 07:58:32.000000000 -0700
+++ binutils/bfd/elf.c	2005-10-20 10:32:57.000000000 -0700
@@ -2670,29 +2670,7 @@ elf_fake_sections (bfd *abfd, asection *
   if (this_hdr->sh_type == SHT_NULL)
     {
       if ((asect->flags & SEC_GROUP) != 0)
-	{
-	  /* We also need to mark SHF_GROUP here for relocatable
-	     link.  */
-	  struct bfd_link_order *l;
-	  asection *elt;
-
-	  for (l = asect->map_head.link_order; l != NULL; l = l->next)
-	    if (l->type == bfd_indirect_link_order
-		&& (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
-	      do
-		{
-		  /* The name is not important. Anything will do.  */
-		  elf_group_name (elt->output_section) = "G";
-		  elf_section_flags (elt->output_section) |= SHF_GROUP;
-
-		  elt = elf_next_in_group (elt);
-		  /* During a relocatable link, the lists are
-		     circular.  */
-		}
-	      while (elt != elf_next_in_group (l->u.indirect.section));
-
-	  this_hdr->sh_type = SHT_GROUP;
-	}
+	this_hdr->sh_type = SHT_GROUP;
       else if ((asect->flags & SEC_ALLOC) != 0
 	  && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
 	      || (asect->flags & SEC_NEVER_LOAD) != 0))
@@ -2827,7 +2805,6 @@ bfd_elf_set_group_contents (bfd *abfd, a
   unsigned long symindx;
   asection *elt, *first;
   unsigned char *loc;
-  struct bfd_link_order *l;
   bfd_boolean gas;
 
   /* Ignore linker created group section.  See elfNN_ia64_object_p in
@@ -2896,22 +2873,6 @@ bfd_elf_set_group_contents (bfd *abfd, a
 	break;
     }
 
-  /* 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->map_head.link_order; 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));
-
   if ((loc -= 4) != sec->contents)
     abort ();
 
@@ -3091,67 +3052,46 @@ assign_section_numbers (bfd *abfd, struc
 	{
 	  s = elf_linked_to_section (sec);
 	  if (s)
-	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
-	  else
 	    {
-	      struct bfd_link_order *p;
-
-	      /* Find out what the corresponding section in output
-		 is.  */
-	      for (p = sec->map_head.link_order; p != NULL; p = p->next)
+	      if (link_info != NULL)
 		{
-		  s = p->u.indirect.section;
-		  if (p->type == bfd_indirect_link_order
-		      && (bfd_get_flavour (s->owner)
-			  == bfd_target_elf_flavour))
+		  /* For linker, elf_linked_to_section points to the
+		     input section.  */
+		  if (elf_discarded_section (s))
 		    {
-		      Elf_Internal_Shdr ** const elf_shdrp
-			= elf_elfsections (s->owner);
-		      int elfsec
-			= _bfd_elf_section_from_bfd_section (s->owner, s);
-		      elfsec = elf_shdrp[elfsec]->sh_link;
-		      /* PR 290:
-			 The Intel C compiler generates SHT_IA_64_UNWIND with
-			 SHF_LINK_ORDER.  But it doesn't set the sh_link or
-			 sh_info fields.  Hence we could get the situation
-		         where elfsec is 0.  */
-		      if (elfsec == 0)
-			{
-			  const struct elf_backend_data *bed
-			    = get_elf_backend_data (abfd);
-			  if (bed->link_order_error_handler)
-			    bed->link_order_error_handler
-			      (_("%B: warning: sh_link not set for section `%A'"),
-			       abfd, s);
-			}
-		      else
+		      asection *kept;
+		      (*_bfd_error_handler)
+			(_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
+			 abfd, d->this_hdr.bfd_section,
+			 s, s->owner);
+		      /* Point to the kept section if it has the same
+			 size as the discarded one.  */
+		      kept = _bfd_elf_check_kept_section (s);
+		      if (kept == NULL)
 			{
-			  s = elf_shdrp[elfsec]->bfd_section;
-			  if (elf_discarded_section (s))
-			    {
-			      asection *kept;
-			       (*_bfd_error_handler)
-				  (_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
-				   abfd, d->this_hdr.bfd_section,
-				   s, s->owner);
-			       /* Point to the kept section if it has
-				  the same size as the discarded
-				  one.  */
-			       kept = _bfd_elf_check_kept_section (s);
-			       if (kept == NULL)
-				 {
-				   bfd_set_error (bfd_error_bad_value);
-				   return FALSE;
-				 }
-			       s = kept;
-			    }
-			  s = s->output_section;
-			  BFD_ASSERT (s != NULL);
-			  d->this_hdr.sh_link = elf_section_data (s)->this_idx;
+			  bfd_set_error (bfd_error_bad_value);
+			  return FALSE;
 			}
-		      break;
+		      s = kept;
 		    }
+		  s = s->output_section;
+		  BFD_ASSERT (s != NULL);
 		}
+	      d->this_hdr.sh_link = elf_section_data (s)->this_idx;
+	    }
+	  else
+	    {
+	      /* PR 290:
+		 The Intel C compiler generates SHT_IA_64_UNWIND with
+		 SHF_LINK_ORDER.  But it doesn't set the sh_link or
+		 sh_info fields.  Hence we could get the situation
+	         where s is NULL.  */
+	      const struct elf_backend_data *bed
+		= get_elf_backend_data (abfd);
+	      if (bed->link_order_error_handler)
+		bed->link_order_error_handler
+		  (_("%B: warning: sh_link not set for section `%A'"),
+		   abfd, sec);
 	    }
 	}
 
@@ -5665,6 +5605,62 @@ copy_private_bfd_data (bfd *ibfd, bfd *o
   return TRUE;
 }
 
+/* Initialize private output section information from input section.  */
+
+bfd_boolean
+_bfd_elf_init_private_section_data (bfd *ibfd,
+				    asection *isec,
+				    bfd *obfd,
+				    asection *osec,
+				    struct bfd_link_info *link_info)
+
+{
+  Elf_Internal_Shdr *ihdr, *ohdr;
+  bfd_boolean need_group = link_info == NULL || link_info->relocatable;
+
+  if (ibfd->xvec->flavour != bfd_target_elf_flavour
+      || obfd->xvec->flavour != bfd_target_elf_flavour)
+    return TRUE;
+
+  /* FIXME: What if the output ELF section type has been set to
+     something different?  */
+  if (elf_section_type (osec) == SHT_NULL)
+    elf_section_type (osec) = elf_section_type (isec);
+
+  /* Set things up for objcopy and relocatable link.  The output
+     SHT_GROUP section will have its elf_next_in_group pointing back
+     to the input group members.  Ignore linker created group section.
+     See elfNN_ia64_object_p in elfxx-ia64.c.  */
+
+  if (need_group)
+    {
+      if (elf_sec_group (isec) == NULL
+	  || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
+	{
+	  if (elf_section_flags (isec) & SHF_GROUP)
+	    elf_section_flags (osec) |= SHF_GROUP;
+	  elf_next_in_group (osec) = elf_next_in_group (isec);
+	  elf_group_name (osec) = elf_group_name (isec);
+	}
+    }
+
+  ihdr = &elf_section_data (isec)->this_hdr;
+
+  /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We
+     don't use the output section of the linked-to section since it
+     may be NULL at this point.  */
+  if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0)
+    {
+      ohdr = &elf_section_data (osec)->this_hdr;
+      ohdr->sh_flags |= SHF_LINK_ORDER;
+      elf_linked_to_section (osec) = elf_linked_to_section (isec);
+    }
+
+  osec->use_rela_p = isec->use_rela_p;
+
+  return TRUE;
+}
+
 /* Copy private section information.  This copies over the entsize
    field, and sometimes the info field.  */
 
@@ -5691,27 +5687,8 @@ _bfd_elf_copy_private_section_data (bfd 
       || ihdr->sh_type == SHT_GNU_verdef)
     ohdr->sh_info = ihdr->sh_info;
 
-  /* Set things up for objcopy.  The output SHT_GROUP section will
-     have its elf_next_in_group pointing back to the input group
-     members.  Ignore linker created group section.  See
-     elfNN_ia64_object_p in elfxx-ia64.c.  We also need to handle
-     elf_linked_to_section for SHF_LINK_ORDER.  */
-
-  if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0
-      && elf_linked_to_section (isec) != 0)
-    elf_linked_to_section (osec)
-      = elf_linked_to_section (isec)->output_section;
-
-  if (elf_sec_group (isec) == NULL
-      || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
-    {
-      elf_next_in_group (osec) = elf_next_in_group (isec);
-      elf_group_name (osec) = elf_group_name (isec);
-    }
-
-  osec->use_rela_p = isec->use_rela_p;
-
-  return TRUE;
+  return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec,
+					     NULL);
 }
 
 /* Copy private header information.  */
--- binutils/bfd/libbfd-in.h.copy	2005-10-15 07:58:32.000000000 -0700
+++ binutils/bfd/libbfd-in.h	2005-10-20 10:12:36.000000000 -0700
@@ -234,6 +234,9 @@ extern bfd_boolean _bfd_generic_get_sect
 #define _bfd_generic_bfd_print_private_bfd_data \
   ((bfd_boolean (*) (bfd *, void *)) bfd_true)
 
+extern bfd_boolean _bfd_generic_init_private_section_data
+  (bfd *, asection *, bfd *, asection *, struct bfd_link_info *);
+
 /* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file
    support.  Use BFD_JUMP_TABLE_CORE (_bfd_nocore).  */
 
--- binutils/bfd/libbfd.c.copy	2005-10-15 07:58:32.000000000 -0700
+++ binutils/bfd/libbfd.c	2005-10-20 10:12:36.000000000 -0700
@@ -1042,3 +1042,13 @@ _bfd_generic_match_sections_by_type (bfd
 {
   return TRUE;
 }
+
+bfd_boolean
+_bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
+					asection *isec ATTRIBUTE_UNUSED,
+					bfd *obfd ATTRIBUTE_UNUSED,
+					asection *osec ATTRIBUTE_UNUSED,
+					struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
+{
+  return TRUE;
+}
--- binutils/bfd/targets.c.copy	2005-10-15 07:58:32.000000000 -0700
+++ binutils/bfd/targets.c	2005-10-20 10:12:36.000000000 -0700
@@ -271,6 +271,7 @@ BFD_JUMP_TABLE macros.
 .#define BFD_JUMP_TABLE_COPY(NAME) \
 .  NAME##_bfd_copy_private_bfd_data, \
 .  NAME##_bfd_merge_private_bfd_data, \
+.  _bfd_generic_init_private_section_data, \
 .  NAME##_bfd_copy_private_section_data, \
 .  NAME##_bfd_copy_private_symbol_data, \
 .  NAME##_bfd_copy_private_header_data, \
@@ -283,6 +284,12 @@ BFD_JUMP_TABLE macros.
 .  {* Called to merge BFD general private data from one object file
 .     to a common output file when linking.  *}
 .  bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *);
+.  {* Called to initialize BFD private section data from one object file
+.     to another.  *}
+.#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \
+.  BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info))
+.  bfd_boolean (*_bfd_init_private_section_data)
+.    (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *);
 .  {* Called to copy BFD private section data from one object file
 .     to another.  *}
 .  bfd_boolean (*_bfd_copy_private_section_data)
--- binutils/ld/emultempl/elf32.em.copy	2005-10-15 07:58:32.000000000 -0700
+++ binutils/ld/emultempl/elf32.em	2005-10-20 10:12:36.000000000 -0700
@@ -1363,8 +1363,9 @@ gld${EMULATION_NAME}_place_orphan (lang_
       if (os != NULL
 	  && (os->bfd_section == NULL
 	      || os->bfd_section->flags == 0
-	      || ((!iself
-		   || sh_type == elf_section_type (os->bfd_section))
+	      || (bfd_match_sections_by_type (output_bfd,
+					      os->bfd_section,
+					      s->owner, s)
 		  && ((s->flags ^ os->bfd_section->flags)
 		      & (SEC_LOAD | SEC_ALLOC)) == 0)))
 	{
--- binutils/ld/ldlang.c.copy	2005-10-15 07:58:32.000000000 -0700
+++ binutils/ld/ldlang.c	2005-10-20 10:12:36.000000000 -0700
@@ -1674,7 +1674,7 @@ sort_def_symbol (hash_entry, info)
 /* Initialize an output section.  */
 
 static void
-init_os (lang_output_section_statement_type *s)
+init_os (lang_output_section_statement_type *s, asection *isec)
 {
   if (s->bfd_section != NULL)
     return;
@@ -1711,6 +1711,11 @@ init_os (lang_output_section_statement_t
 
   if (s->load_base != NULL)
     exp_init_os (s->load_base);
+
+  if (isec)
+    bfd_init_private_section_data (isec->owner, isec,
+				   output_bfd, s->bfd_section,
+				   &link_info);
 }
 
 /* Make sure that all output sections mentioned in an expression are
@@ -1756,7 +1761,7 @@ exp_init_os (etree_type *exp)
 
 	    os = lang_output_section_find (exp->name.name);
 	    if (os != NULL && os->bfd_section == NULL)
-	      init_os (os);
+	      init_os (os, NULL);
 	  }
 	}
       break;
@@ -1833,7 +1838,7 @@ lang_add_section (lang_statement_list_ty
       flagword flags;
 
       if (output->bfd_section == NULL)
-	init_os (output);
+	init_os (output, section);
 
       first = ! output->bfd_section->linker_has_input;
       output->bfd_section->linker_has_input = 1;
@@ -3099,7 +3104,7 @@ map_input_to_output_sections
 	     are initialized.  */
 	  exp_init_os (s->data_statement.exp);
 	  if (os != NULL && os->bfd_section == NULL)
-	    init_os (os);
+	    init_os (os, NULL);
 	  /* The output section gets contents, and then we inspect for
 	     any flags set in the input script which override any ALLOC.  */
 	  os->bfd_section->flags |= SEC_HAS_CONTENTS;
@@ -3113,11 +3118,11 @@ map_input_to_output_sections
 	case lang_padding_statement_enum:
 	case lang_input_statement_enum:
 	  if (os != NULL && os->bfd_section == NULL)
-	    init_os (os);
+	    init_os (os, NULL);
 	  break;
 	case lang_assignment_statement_enum:
 	  if (os != NULL && os->bfd_section == NULL)
-	    init_os (os);
+	    init_os (os, NULL);
 
 	  /* Make sure that any sections mentioned in the assignment
 	     are initialized.  */
@@ -3145,7 +3150,7 @@ map_input_to_output_sections
 		   (s->address_statement.section_name));
 	      
 	      if (aos->bfd_section == NULL)
-		init_os (aos);
+		init_os (aos, NULL);
 	      aos->addr_tree = s->address_statement.address;
 	    }
 	  break;
--- binutils/ld/testsuite/ld-ia64/tlspic.rd.copy	2005-08-24 08:27:16.000000000 -0700
+++ binutils/ld/testsuite/ld-ia64/tlspic.rd	2005-10-20 10:12:36.000000000 -0700
@@ -61,7 +61,6 @@ Symbol table '.dynsym' contains [0-9]+ e
 .* NOTYPE +LOCAL +DEFAULT +UND *
 .* SECTION LOCAL +DEFAULT +7 *
 .* SECTION LOCAL +DEFAULT +8 *
-.* SECTION LOCAL +DEFAULT +9 *
 .* SECTION LOCAL +DEFAULT +10 *
 .* SECTION LOCAL +DEFAULT +11 *
 .* SECTION LOCAL +DEFAULT +14 *


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