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: ld/1487: ELF input section may not be handled properly


On Sun, Oct 16, 2005 at 10:40:16AM -0700, H. J. Lu wrote:
> > set. Gcc uses orphan sections to check HAVE_LD_RO_RW_SECTION_MIXING.
> 
> I opened a bug for it:
> 
> http://sources.redhat.com/bugzilla/show_bug.cgi?id=1487
> 
> My patch doesn't fix it. I am working on a differnt patch.
> 

We aren't doing a good job for seting up proper ELF output section
header from ELF input section. The problem shows up with ld and
objcopy. This patch tries to set section type correctly.


H.J.
----
bfd/

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

	PR ld/1487
	* elf.c (elf_fake_sections): Don't set SHF_GROUP for
	relocatable link.
	(bfd_elf_set_group_contents): Don't handle relocatable link
	specially.
	(_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-16  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.

--- binutils/bfd/elf.c.copy	2005-10-15 07:58:32.000000000 -0700
+++ binutils/bfd/elf.c	2005-10-16 19:40:22.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 ();
 
@@ -5665,6 +5626,49 @@ 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)
+
+{
+  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.  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);
+	}
+    }
+
+  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 +5695,16 @@ _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.  */
+  /* Set things up for objcopy.  We 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-16 18:17:54.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-16 18:17:54.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-16 18:17:54.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-16 18:17:54.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-16 19:23:47.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;


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