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

Re: RFC: Add bfd_get_section_ident


On Fri, May 28, 2004 at 05:59:12PM -0400, Ian Lance Taylor wrote:
> "H. J. Lu" <hjl@lucon.org> writes:
> 
> > Here is the start. I can make other changes to make
> > 
> > # objdump -j section
> > 
> > work with multiple sections with the same name.
> 
> bfd_get_section_ident() is a space leak.  It should use bfd_alloc(),
> not bfd_malloc().  If allocation fails, I think it should return NULL,
> not silently return the wrong value.  (This is more or less the
> conversation we just had a couple of weeks ago.)
> 
> Now, that said, do we really need two new fields in asection?  That
> can be pretty costly in the linker, with regard to memory space.
> 

This patch changes comdat into a union and only adds a pointe per
section.


H.J.
----
bfd/

2004-06-04  H.J. Lu  <hongjiu.lu@intel.com>

	* elf-bfd.h (_bfd_elf_setup_group_pointers): New prototype.

	* elf.c (_bfd_elf_setup_group_pointers): New function.

	* elfcode.h (elf_object_p): Call _bfd_elf_setup_group_pointers.

	* elflink.c (elf_link_read_relocs_from_section): Call
	bfd_get_section_ident to identify the section when reporting
	error.
	(_bfd_elf_link_output_relocs): Likewise.
	(elf_link_output_extsym): Likewise.
	(elf_link_input_bfd): Likewise.
	(bfd_elf_gc_record_vtinherit): Likewise.

	* section.c (bfd_group_info): New structure for section group.
	(bfd_section): Change comdat to a union of a pointer to
	struct bfd_comdat_info and a pointer to struct bfd_group_info.
	(bfd_get_section_ident): New.

	* section (STD_SECTION): Updated.
	* ecoff.c (bfd_debug_section): Likewise.

	* bfd-in2.h: Regenerated.

binutils/

2004-06-04  H.J. Lu  <hongjiu.lu@intel.com>

	* objcopy.c (filter_symbols): Check comdat for COFF targets
	only.
	* objdump.c (dump_section_header): Likewise.

ld/

2004-06-04  H.J. Lu  <hongjiu.lu@intel.com>

	* ldlang.c (section_already_linked): Check comdat for COFF
	targets only.

--- binutils/bfd/ecoff.c.ident	2004-05-10 07:18:09.000000000 -0700
+++ binutils/bfd/ecoff.c	2004-06-04 13:56:41.000000000 -0700
@@ -95,8 +95,8 @@ static asection bfd_debug_section =
      NULL,       NULL,        0,           0,       0,
   /* line_filepos, userdata, contents, lineno, lineno_count,       */
      0,            NULL,     NULL,     NULL,   0,
-  /* entsize, comdat, kept_section, moving_line_filepos,           */
-     0,       NULL,   NULL,         0,
+  /* entsize, u,      kept_section, moving_line_filepos,           */
+     0,       {NULL}, NULL,         0,
   /* target_index, used_by_bfd, constructor_chain, owner,          */
      0,            NULL,        NULL,              NULL,
   /* symbol,                                                       */
--- binutils/bfd/elf-bfd.h.ident	2004-05-17 18:59:14.000000000 -0700
+++ binutils/bfd/elf-bfd.h	2004-06-04 13:20:55.620012414 -0700
@@ -1556,6 +1556,9 @@ extern bfd_boolean _bfd_elf_dynamic_symb
 extern bfd_boolean _bfd_elf_symbol_refs_local_p
   (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean);
 
+extern void _bfd_elf_setup_group_pointers
+  (bfd *);
+
 extern const bfd_target *bfd_elf32_object_p
   (bfd *);
 extern const bfd_target *bfd_elf32_core_file_p
--- binutils/bfd/elf.c.ident	2004-05-28 14:31:37.000000000 -0700
+++ binutils/bfd/elf.c	2004-06-04 14:11:08.000000000 -0700
@@ -612,6 +612,37 @@ setup_group (bfd *abfd, Elf_Internal_Shd
   return TRUE;
 }
 
+void
+_bfd_elf_setup_group_pointers (bfd *abfd)
+{
+  unsigned int i;
+  unsigned int num_group = elf_tdata (abfd)->num_group;
+
+  if (num_group == (unsigned) -1)
+    return;
+
+  for (i = 0; i < num_group; i++)
+    {
+      Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
+      Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
+      unsigned int n_elt = shdr->sh_size / 4;
+
+      while (--n_elt != 0)
+	if ((++idx)->shdr->bfd_section)
+	  {
+	    if (idx->shdr->bfd_section->u.group == NULL)
+	      {
+	       	idx->shdr->bfd_section->u.group
+		  = bfd_alloc (idx->shdr->bfd_section->owner,
+			       sizeof (struct bfd_group_info));
+	       	if (idx->shdr->bfd_section->u.group == NULL)
+		  abort ();
+	      }
+	    idx->shdr->bfd_section->u.group->group = shdr->bfd_section;
+	  }
+    }
+}
+
 bfd_boolean
 bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
 {
--- binutils/bfd/elfcode.h.ident	2004-05-10 07:18:14.000000000 -0700
+++ binutils/bfd/elfcode.h	2004-06-04 13:20:55.000000000 -0700
@@ -742,6 +742,9 @@ elf_object_p (bfd *abfd)
 	  if (shindex == SHN_LORESERVE - 1)
 	    shindex += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 	}
+
+      /* Set up group pointers.  */
+      _bfd_elf_setup_group_pointers (abfd);
     }
 
   /* Let the backend double check the format and override global
--- binutils/bfd/elflink.c.ident	2004-05-25 22:45:53.000000000 -0700
+++ binutils/bfd/elflink.c	2004-06-04 13:20:55.000000000 -0700
@@ -1850,7 +1850,8 @@ elf_link_read_relocs_from_section (bfd *
 	  (*_bfd_error_handler)
 	    (_("%s: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%s'"),
 	     bfd_archive_filename (abfd), (unsigned long) r_symndx,
-	     (unsigned long) nsyms, irela->r_offset, sec->name);
+	     (unsigned long) nsyms, irela->r_offset, 
+	      bfd_get_section_ident (sec));
 	  bfd_set_error (bfd_error_bad_value);
 	  return FALSE;
 	}
@@ -2040,7 +2041,7 @@ _bfd_elf_link_output_relocs (bfd *output
 	(_("%s: relocation size mismatch in %s section %s"),
 	 bfd_get_filename (output_bfd),
 	 bfd_archive_filename (input_section->owner),
-	 input_section->name);
+	 bfd_get_section_ident (input_section));
       bfd_set_error (bfd_error_wrong_object_format);
       return FALSE;
     }
@@ -6068,8 +6069,8 @@ elf_link_output_extsym (struct elf_link_
 		(*_bfd_error_handler)
 		  (_("%s: could not find output section %s for input section %s"),
 		   bfd_get_filename (finfo->output_bfd),
-		   input_sec->output_section->name,
-		   input_sec->name);
+		   bfd_get_section_ident (input_sec->output_section),
+		   bfd_get_section_ident (input_sec));
 		eoinfo->failed = TRUE;
 		return FALSE;
 	      }
@@ -6587,7 +6588,7 @@ elf_link_input_bfd (struct elf_final_lin
 			       _("%T: discarded in section `%s' from %s\n"),
 			       h->root.root.string,
 			       h->root.root.string,
-			       h->root.u.def.section->name,
+			       bfd_get_section_ident (h->root.u.def.section),
 			       bfd_archive_filename (h->root.u.def.section->owner));
 			}
 		    }
@@ -6626,7 +6627,7 @@ elf_link_input_bfd (struct elf_final_lin
 			      finfo->info->callbacks->error_handler
 				(LD_DEFINITION_IN_DISCARDED_SECTION,
 				 _("%T: discarded in section `%s' from %s\n"),
-				 buf, buf, sec->name,
+				 buf, buf, bfd_get_section_ident (sec),
 				 bfd_archive_filename (input_bfd));
 			      if (ok != -1)
 				free (buf);
@@ -8566,7 +8567,8 @@ bfd_elf_gc_record_vtinherit (bfd *abfd,
     }
 
   (*_bfd_error_handler) ("%s: %s+%lu: No symbol found for INHERIT",
-			 bfd_archive_filename (abfd), sec->name,
+			 bfd_archive_filename (abfd),
+			  bfd_get_section_ident (sec),
 			 (unsigned long) offset);
   bfd_set_error (bfd_error_invalid_operation);
   return FALSE;
--- binutils/bfd/section.c.ident	2004-05-10 07:18:16.000000000 -0700
+++ binutils/bfd/section.c	2004-06-04 14:10:42.000000000 -0700
@@ -166,6 +166,22 @@ CODE_FRAGMENT
 .  long symbol;
 .};
 .
+.{* This structure is used for a section in a section group, as in ELF.
+.   A section can belong to a section group. When linker discard a
+.   section in a section group, all sections in the group will be
+.   discarded.  *}
+.
+.struct bfd_group_info
+.{
+.  {* The identifier of the section; the identifier is unique within
+.     the file.  *}
+.  const char *ident;
+.
+.  {* Optional information about section group; NULL if it doesn't
+.     belongs to any section group.  *}
+.  struct bfd_section *group;
+.};
+.
 .typedef struct bfd_section
 .{
 .  {* The name of the section; the name isn't a copy, the pointer is
@@ -490,8 +506,13 @@ CODE_FRAGMENT
 .  {* Entity size for merging purposes.  *}
 .  unsigned int entsize;
 .
-.  {* Optional information about a COMDAT entry; NULL if not COMDAT.  *}
-.  struct bfd_comdat_info *comdat;
+.  {* Optional information about a COMDAT or GROUP entry; NULL if not
+.     COMDAT nor GROUP.  *}
+.  union
+.    {
+.      struct bfd_comdat_info *comdat;
+.      struct bfd_group_info *group;
+.    } u;
 .
 .  {* Points to the kept section if this section is a link-once section,
 .     and is discarded.  *}
@@ -643,8 +664,8 @@ static const asymbol global_syms[] =
     /* line_filepos, userdata, contents, lineno, lineno_count,       */	\
        0,            NULL,     NULL,     NULL,   0,			\
 									\
-    /* entsize, comdat, kept_section, moving_line_filepos,           */	\
-       0,       NULL,   NULL,	      0,				\
+    /* entsize, u,	kept_section, moving_line_filepos,           */	\
+       0,       {NULL}, NULL,	      0,				\
 									\
     /* target_index, used_by_bfd, constructor_chain, owner,          */	\
        0,            NULL,        NULL,              NULL,		\
@@ -1476,3 +1497,53 @@ bfd_generic_discard_group (bfd *abfd ATT
 {
   return TRUE;
 }
+
+/*
+FUNCTION
+	bfd_get_section_ident
+
+SYNOPSIS
+	const char *bfd_get_section_ident (asection *sec);
+
+DESCRIPTION
+	Return the section identifier of @var{sec}.
+*/
+
+const char *
+bfd_get_section_ident (asection *sec)
+{
+  if (sec->owner == NULL
+      || bfd_get_flavour (sec->owner) != bfd_target_elf_flavour)
+    return sec->name;
+
+  if (sec->u.group == NULL)
+    {
+      sec->u.group = bfd_alloc (sec->owner,
+			       	sizeof (struct bfd_group_info));
+      if (sec->u.group == NULL)
+       	abort ();
+    }
+
+  if (sec->u.group->ident == NULL)
+    {
+      if (sec->u.group->group == NULL)
+	sec->u.group->ident = sec->name;
+      else if (sec->owner != NULL)
+	{
+	  bfd_size_type nlen = strlen (sec->name);
+	  bfd_size_type glen = strlen (sec->u.group->group->name);
+	  char *buf = bfd_alloc (sec->owner, nlen + glen + 2 + 1);
+	  if (buf != NULL)
+	    {
+	      strcpy (buf, sec->name);
+	      buf [nlen] = '[';
+	      strcpy (&buf [nlen + 1], sec->u.group->group->name);
+	      buf [nlen + 1 + glen] = ']';
+	      buf [nlen + 1 + glen + 1] = '\0';
+	      sec->u.group->ident = buf;
+	    }
+	} 
+    }
+
+  return sec->u.group->ident;
+}
--- binutils/binutils/objcopy.c.ident	2004-05-17 18:59:09.000000000 -0700
+++ binutils/binutils/objcopy.c	2004-06-04 14:26:25.000000000 -0700
@@ -891,7 +891,8 @@ filter_symbols (bfd *abfd, bfd *obfd, as
 	keep = (strip_symbols != STRIP_DEBUG
 		&& strip_symbols != STRIP_UNNEEDED
 		&& ! convert_debugging);
-      else if (bfd_get_section (sym)->comdat)
+      else if (bfd_get_flavour (abfd) == bfd_target_coff_flavour
+	       && bfd_get_section (sym)->u.comdat)
 	/* COMDAT sections store special information in local
 	   symbols, so we cannot risk stripping any of them.  */
 	keep = 1;
--- binutils/binutils/objdump.c.ident	2004-05-10 07:18:06.000000000 -0700
+++ binutils/binutils/objdump.c	2004-06-04 14:27:01.000000000 -0700
@@ -287,7 +287,7 @@ nonfatal (const char *msg)
 }
 
 static void
-dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, asection *section,
+dump_section_header (bfd *abfd, asection *section,
 		     void *ignored ATTRIBUTE_UNUSED)
 {
   char *comma = "";
@@ -351,9 +351,10 @@ dump_section_header (bfd *abfd ATTRIBUTE
 	}
       printf ("%s%s", comma, ls);
 
-      if (section->comdat != NULL)
-	printf (" (COMDAT %s %ld)", section->comdat->name,
-		section->comdat->symbol);
+      if (bfd_get_flavour (abfd) == bfd_target_coff_flavour
+	  && section->u.comdat != NULL)
+	printf (" (COMDAT %s %ld)", section->u.comdat->name,
+		section->u.comdat->symbol);
 
       comma = ", ";
     }
--- binutils/ld/ldlang.c.ident	2004-06-04 13:19:36.000000000 -0700
+++ binutils/ld/ldlang.c	2004-06-04 14:39:20.115104979 -0700
@@ -959,9 +959,11 @@ section_already_linked (bfd *abfd, asect
 
   for (l = already_linked_list->entry; l != NULL; l = l->next)
     {
-      if (sec->comdat == NULL
-	  || l->sec->comdat == NULL
-	  || strcmp (sec->comdat->name, l->sec->comdat->name) == 0)
+      if (sec->u.comdat == NULL
+	  || l->sec->u.comdat == NULL
+	  && (bfd_get_flavour (sec->owner) == bfd_target_coff_flavour
+	      || strcmp (sec->u.comdat->name,
+			 l->sec->u.comdat->name) == 0))
 	{
 	  /* The section has already been linked.  See if we should
              issue a warning.  */
@@ -974,13 +976,14 @@ section_already_linked (bfd *abfd, asect
 	      break;
 
 	    case SEC_LINK_DUPLICATES_ONE_ONLY:
-	      if (sec->comdat == NULL)
+	      if (bfd_get_flavour (sec->owner) != bfd_target_coff_flavour
+		  || sec->u.comdat == NULL)
 		einfo (_("%P: %B: warning: ignoring duplicate section `%s'\n"),
 		       abfd, name);
 	      else
 		einfo (_("%P: %B: warning: ignoring duplicate `%s'"
 			 " section symbol `%s'\n"),
-		       abfd, name, sec->comdat->name);
+		       abfd, name, sec->u.comdat->name);
 	      break;
 
 	    case SEC_LINK_DUPLICATES_SAME_CONTENTS:


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