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