SHT_GROUP naming

Alan Modra amodra@bigpond.net.au
Fri Jun 7 07:56:00 GMT 2002


http://www.codesourcery.com/cxx-abi/abi/prop-72-comdat.html says:

"Why use a symbol to identify a (COMDAT) group instead of the group
section name?

Answer: These will be very common in C++, and the typical names in C++
can be extremely long (for template instantiations often multiple
kilobytes in current implementations, and probably 100+ characters on
average even if vastly better mangling is adopted).  Virtually all such
sections must already define a real global symbol, and duplicating
such long names in the section name string table is undesirable space
overhead.

Seems reasonable enough to me.  This patch allows a non-section symbol
to be used for the group name, and chooses a simple section name.  At
the moment, objcopy and "ld -r" will cause the old behaviour of naming
the group section by its signature.

Also gets rid of a few memset calls.  More to follow in the next patch.

bfd/ChangeLog
	* elf-bfd.h (struct bfd_elf_section_data <group_name>): Replace with
	"group" union.
	(elf_group_name): Update.
	(elf_group_id): Define.
	(bfd_elf_set_group_contents): Declare.
	* elf.c (elf_fake_sections): Qualify use of elf_group_name.
	(set_group_contents): Rename to bfd_elf_set_group_contents.  Remove
	ATTRIBUTE_UNUSED from failedptrarg.  If elf_group_id is set, use
	that sym for the signature.
	(_bfd_elf_compute_section_file_positions): Don't call
	set_group_contents for "ld -r" case.
	(swap_out_syms): Use bfd_zalloc.
	* elflink.h (elf_link_add_archive_symbols): Likewise.
	(NAME(bfd_elf,size_dynamic_sections)): Likewise.
	(elf_bfd_final_link): Call bfd_elf_set_group_contents.

gas/ChangeLog
	* symbols.c: Replace CONST by const throughout.
	(symbol_find_exact): Split out from..
	(symbol_find_base): ..here.
	* symbols.h: Replace CONST by const throughout.
	(symbol_find_exact): Declare.
	* config/obj-elf.c: #include "struc-symbol.h".
	(elf_frob_file): If group name matches an exported symbol, use that
	symbol for the signature and ".group" as the section name.

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.78
diff -u -p -r1.78 elf-bfd.h
--- bfd/elf-bfd.h	6 Jun 2002 00:29:20 -0000	1.78
+++ bfd/elf-bfd.h	7 Jun 2002 12:46:36 -0000
@@ -916,8 +916,13 @@ struct bfd_elf_section_data
   /* Type of that information.  */
   enum elf_link_info_type sec_info_type;
 
-  /* Group name, if this section is part of a group.  */
-  const char *group_name;
+  union {
+    /* Group name, if this section is a member of a group.  */
+    const char *name;
+
+    /* Group signature sym, if this is the SHT_GROUP section.  */
+    struct symbol_cache_entry *id;
+  } group;
 
   /* A linked list of sections in the group.  Circular when used by
      the linker.  */
@@ -934,7 +939,8 @@ struct bfd_elf_section_data
 };
 
 #define elf_section_data(sec)  ((struct bfd_elf_section_data*)sec->used_by_bfd)
-#define elf_group_name(sec)    (elf_section_data(sec)->group_name)
+#define elf_group_name(sec)    (elf_section_data(sec)->group.name)
+#define elf_group_id(sec)      (elf_section_data(sec)->group.id)
 #define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group)
 #define elf_linkonce_p(sec)    (elf_section_data(sec)->linkonce_p)
 
@@ -1265,6 +1271,8 @@ extern boolean _bfd_elf_merge_sections
   PARAMS ((bfd *, struct bfd_link_info *));
 extern boolean bfd_elf_discard_group
   PARAMS ((bfd *, struct sec *));
+extern void bfd_elf_set_group_contents
+  PARAMS ((bfd *, asection *, PTR));
 extern void _bfd_elf_link_just_syms
   PARAMS ((asection *, struct bfd_link_info *));
 extern boolean _bfd_elf_copy_private_symbol_data
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.145
diff -u -p -r1.145 elf.c
--- bfd/elf.c	6 Jun 2002 10:03:36 -0000	1.145
+++ bfd/elf.c	7 Jun 2002 12:46:42 -0000
@@ -54,7 +54,6 @@ static const char *group_signature PARAM
 static boolean setup_group PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
 static void merge_sections_remove_hook PARAMS ((bfd *, asection *));
 static void elf_fake_sections PARAMS ((bfd *, asection *, PTR));
-static void set_group_contents PARAMS ((bfd *, asection *, PTR));
 static boolean assign_section_numbers PARAMS ((bfd *));
 static INLINE int sym_is_global PARAMS ((bfd *, asymbol *));
 static boolean elf_map_symbols PARAMS ((bfd *));
@@ -2358,7 +2357,7 @@ elf_fake_sections (abfd, asect, failedpt
       if ((asect->flags & SEC_STRINGS) != 0)
 	this_hdr->sh_flags |= SHF_STRINGS;
     }
-  if (elf_group_name (asect) != NULL)
+  if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL)
     this_hdr->sh_flags |= SHF_GROUP;
   if ((asect->flags & SEC_THREAD_LOCAL) != 0)
     this_hdr->sh_flags |= SHF_TLS;
@@ -2382,11 +2381,11 @@ elf_fake_sections (abfd, asect, failedpt
 
 /* Fill in the contents of a SHT_GROUP section.  */
 
-static void
-set_group_contents (abfd, sec, failedptrarg)
+void
+bfd_elf_set_group_contents (abfd, sec, failedptrarg)
      bfd *abfd;
      asection *sec;
-     PTR failedptrarg ATTRIBUTE_UNUSED;
+     PTR failedptrarg;
 {
   boolean *failedptr = (boolean *) failedptrarg;
   unsigned long symindx;
@@ -2399,16 +2398,22 @@ set_group_contents (abfd, sec, failedptr
       || *failedptr)
     return;
 
-  /* If called from the assembler, swap_out_syms will have set up
-     elf_section_syms;  If called for "ld -r", the symbols won't yet
-     be mapped, so emulate elf_bfd_final_link.  */
-  if (elf_section_syms (abfd) != NULL)
-    symindx = elf_section_syms (abfd)[sec->index]->udata.i;
-  else
-    symindx = elf_section_data (sec)->this_idx;
+  symindx = 0;
+  if (elf_group_id (sec) != NULL)
+    symindx = elf_group_id (sec)->udata.i;
+
+  if (symindx == 0)
+    {
+      /* If called from the assembler, swap_out_syms will have set up
+	 elf_section_syms;  If called for "ld -r", use target_index.  */
+      if (elf_section_syms (abfd) != NULL)
+	symindx = elf_section_syms (abfd)[sec->index]->udata.i;
+      else
+	symindx = sec->target_index;
+    }
   elf_section_data (sec)->this_hdr.sh_info = symindx;
 
-  /* Nor will the contents be allocated for "ld -r" or objcopy.  */
+  /* The contents won't be allocated for "ld -r" or objcopy.  */
   gas = true;
   if (sec->contents == NULL)
     {
@@ -2959,9 +2964,9 @@ _bfd_elf_compute_section_file_positions 
 	return false;
     }
 
-  if (link_info == NULL || link_info->relocateable)
+  if (link_info == NULL)
     {
-      bfd_map_over_sections (abfd, set_group_contents, &failed);
+      bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
       if (failed)
 	return false;
     }
@@ -5144,10 +5149,9 @@ swap_out_syms (abfd, sttp, relocatable_p
   if (symtab_shndx_hdr->sh_name != 0)
     {
       amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
-      outbound_shndx = bfd_alloc (abfd, amt);
+      outbound_shndx = bfd_zalloc (abfd, amt);
       if (outbound_shndx == NULL)
 	return false;
-      memset (outbound_shndx, 0, (unsigned long) amt);
       symtab_shndx_hdr->contents = outbound_shndx;
       symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
       symtab_shndx_hdr->sh_size = amt;
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.164
diff -u -p -r1.164 elflink.h
--- bfd/elflink.h	6 Jun 2002 00:29:20 -0000	1.164
+++ bfd/elflink.h	7 Jun 2002 12:46:54 -0000
@@ -313,12 +313,10 @@ elf_link_add_archive_symbols (abfd, info
     return true;
   amt = c;
   amt *= sizeof (boolean);
-  defined = (boolean *) bfd_malloc (amt);
-  included = (boolean *) bfd_malloc (amt);
+  defined = (boolean *) bfd_zmalloc (amt);
+  included = (boolean *) bfd_zmalloc (amt);
   if (defined == (boolean *) NULL || included == (boolean *) NULL)
     goto error_return;
-  memset (defined, 0, (size_t) amt);
-  memset (included, 0, (size_t) amt);
 
   symdefs = bfd_ardata (abfd)->symdefs;
 
@@ -3665,10 +3663,9 @@ NAME(bfd_elf,size_dynamic_sections) (out
       BFD_ASSERT (s != NULL);
       hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize;
       s->_raw_size = ((2 + bucketcount + dynsymcount) * hash_entry_size);
-      s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
+      s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->_raw_size);
       if (s->contents == NULL)
 	return false;
-      memset (s->contents, 0, (size_t) s->_raw_size);
 
       bfd_put (8 * hash_entry_size, output_bfd, (bfd_vma) bucketcount,
 	       s->contents);
@@ -5809,6 +5806,15 @@ elf_bfd_final_link (abfd, info)
 		goto error_return;
 	    }
 	}
+    }
+
+  if (info->relocateable)
+    {
+      boolean failed = false;
+
+      bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
+      if (failed)
+	goto error_return;
     }
 
   /* If we have optimized stabs strings, output them.  *
Index: gas/symbols.c
===================================================================
RCS file: /cvs/src/src/gas/symbols.c,v
retrieving revision 1.34
diff -u -p -r1.34 symbols.c
--- gas/symbols.c	18 May 2002 12:53:30 -0000	1.34
+++ gas/symbols.c	7 Jun 2002 12:47:29 -0000
@@ -1,6 +1,6 @@
 /* symbols.c -symbol table-
    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001
+   1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -569,7 +569,7 @@ symbol_find_or_make (name)
 
 symbolS *
 symbol_make (name)
-     CONST char *name;
+     const char *name;
 {
   symbolS *symbolP;
 
@@ -589,7 +589,7 @@ symbol_make (name)
 
 symbolS *
 symbol_find (name)
-     CONST char *name;
+     const char *name;
 {
 #ifdef STRIP_UNDERSCORE
   return (symbol_find_base (name, 1));
@@ -599,8 +599,25 @@ symbol_find (name)
 }
 
 symbolS *
+symbol_find_exact (name)
+     const char *name;
+{
+#ifdef BFD_ASSEMBLER
+  {
+    struct local_symbol *locsym;
+
+    locsym = (struct local_symbol *) hash_find (local_hash, name);
+    if (locsym != NULL)
+      return (symbolS *) locsym;
+  }
+#endif
+
+  return ((symbolS *) hash_find (sy_hash, name));
+}
+
+symbolS *
 symbol_find_base (name, strip_underscore)
-     CONST char *name;
+     const char *name;
      int strip_underscore;
 {
   if (strip_underscore && *name == '_')
@@ -633,17 +650,7 @@ symbol_find_base (name, strip_underscore
       *copy = '\0';
     }
 
-#ifdef BFD_ASSEMBLER
-  {
-    struct local_symbol *locsym;
-
-    locsym = (struct local_symbol *) hash_find (local_hash, name);
-    if (locsym != NULL)
-      return (symbolS *) locsym;
-  }
-#endif
-
-  return ((symbolS *) hash_find (sy_hash, name));
+  return symbol_find_exact (name);
 }
 
 /* Once upon a time, symbols were kept in a singly linked list.  At
@@ -1816,7 +1838,7 @@ S_IS_STABD (s)
   return S_GET_NAME (s) == 0;
 }
 
-CONST char *
+const char *
 S_GET_NAME (s)
      symbolS *s;
 {
Index: gas/symbols.h
===================================================================
RCS file: /cvs/src/src/gas/symbols.h,v
retrieving revision 1.7
diff -u -p -r1.7 symbols.h
--- gas/symbols.h	9 Sep 2001 14:01:16 -0000	1.7
+++ gas/symbols.h	7 Jun 2002 12:47:30 -0000
@@ -1,6 +1,6 @@
 /* symbols.h -
-   Copyright 1987, 1990, 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+   Copyright 1987, 1990, 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001,
+   2002 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -48,13 +48,14 @@ extern int symbol_table_frozen;
 extern int symbols_case_sensitive;
 
 char *decode_local_label_name PARAMS ((char *s));
-symbolS *symbol_find PARAMS ((CONST char *name));
-symbolS *symbol_find_base PARAMS ((CONST char *name, int strip_underscore));
+symbolS *symbol_find PARAMS ((const char *name));
+symbolS *symbol_find_exact PARAMS ((const char *name));
+symbolS *symbol_find_base PARAMS ((const char *name, int strip_underscore));
 symbolS *symbol_find_or_make PARAMS ((const char *name));
-symbolS *symbol_make PARAMS ((CONST char *name));
-symbolS *symbol_new PARAMS ((CONST char *name, segT segment, valueT value,
+symbolS *symbol_make PARAMS ((const char *name));
+symbolS *symbol_new PARAMS ((const char *name, segT segment, valueT value,
 			     fragS * frag));
-symbolS *symbol_create PARAMS ((CONST char *name, segT segment, valueT value,
+symbolS *symbol_create PARAMS ((const char *name, segT segment, valueT value,
 				fragS * frag));
 symbolS *colon PARAMS ((const char *sym_name));
 void local_colon PARAMS ((int n));
@@ -89,7 +90,7 @@ extern int S_IS_EXTERNAL PARAMS ((symbol
 extern int S_IS_LOCAL PARAMS ((symbolS *));
 extern int S_IS_EXTERN PARAMS ((symbolS *));
 extern int S_IS_STABD PARAMS ((symbolS *));
-extern CONST char *S_GET_NAME PARAMS ((symbolS *));
+extern const char *S_GET_NAME PARAMS ((symbolS *));
 extern segT S_GET_SEGMENT PARAMS ((symbolS *));
 extern void S_SET_SEGMENT PARAMS ((symbolS *, segT));
 extern void S_SET_EXTERNAL PARAMS ((symbolS *));
Index: gas/config/obj-elf.c
===================================================================
RCS file: /cvs/src/src/gas/config/obj-elf.c,v
retrieving revision 1.51
diff -u -p -r1.51 obj-elf.c
--- gas/config/obj-elf.c	4 Jun 2002 01:06:16 -0000	1.51
+++ gas/config/obj-elf.c	7 Jun 2002 12:47:36 -0000
@@ -24,6 +24,7 @@
 #include "safe-ctype.h"
 #include "subsegs.h"
 #include "obstack.h"
+#include "struc-symbol.h"
 
 #ifndef ECOFF_DEBUGGING
 #define ECOFF_DEBUGGING 0
@@ -2024,8 +2025,11 @@ elf_frob_file ()
   for (i = 0; i < list.num_group; i++)
     {
       const char *group_name = elf_group_name (list.head[i]);
+      const char *sec_name;
       asection *s;
       flagword flags;
+      struct symbol *sy;
+      int has_sym;
 
       flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
       for (s = list.head[i]; s != NULL; s = elf_next_in_group (s))
@@ -2040,7 +2044,18 @@ elf_frob_file ()
 	      }
 	  }
 
-      s = subseg_force_new (group_name, 0);
+      sec_name = group_name;
+      sy = symbol_find_exact (group_name);
+      has_sym = 0;
+      if (sy != NULL
+	  && (sy == symbol_lastP
+	      || (sy->sy_next != NULL
+		  && sy->sy_next->sy_previous == sy)))
+	{
+	  has_sym = 1;
+	  sec_name = ".group";
+	}
+      s = subseg_force_new (sec_name, 0);
       if (s == NULL
 	  || !bfd_set_section_flags (stdoutput, s, flags)
 	  || !bfd_set_section_alignment (stdoutput, s, 2))
@@ -2051,6 +2066,8 @@ elf_frob_file ()
 
       /* Pass a pointer to the first section in this group.  */
       elf_next_in_group (s) = list.head[i];
+      if (has_sym)
+	elf_group_id (s) = sy->bsym;
 
       s->_raw_size = 4 * (list.elt_count[i] + 1);
       s->contents = frag_more (s->_raw_size);

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Binutils mailing list