This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
PATCH: Add bfd_get_section_ident
- From: "H. J. Lu" <hjl at lucon dot org>
- To: amodra at bigpond dot net dot au, binutils at sources dot redhat dot com
- Cc: ian at wasabisystems dot com
- Date: Mon, 21 Jun 2004 18:57:16 -0700
- Subject: PATCH: Add bfd_get_section_ident
This patch implements the unique section identifier.
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.
* coffcode.h (handle_COMDAT): Likewise.
* cofflink.c (coff_link_add_symbols): 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/coffcode.h.ident 2004-06-21 11:24:27.000000000 -0700
+++ binutils/bfd/coffcode.h 2004-06-21 17:03:37.747311587 -0700
@@ -966,11 +966,11 @@ handle_COMDAT (abfd, sec_flags, hdr, nam
least) spreads them out. */
amt = sizeof (struct bfd_comdat_info);
- section->comdat = bfd_alloc (abfd, amt);
- if (section->comdat == NULL)
+ section->u.comdat = bfd_alloc (abfd, amt);
+ if (section->u.comdat == NULL)
abort ();
- section->comdat->symbol =
+ section->u.comdat->symbol =
(esym - esymstart) / bfd_coff_symesz (abfd);
amt = strlen (symname) + 1;
@@ -979,7 +979,7 @@ handle_COMDAT (abfd, sec_flags, hdr, nam
abort ();
strcpy (newname, symname);
- section->comdat->name = newname;
+ section->u.comdat->name = newname;
}
goto breakloop;
--- binutils/bfd/cofflink.c.ident 2003-11-24 11:56:50.000000000 -0800
+++ binutils/bfd/cofflink.c 2004-06-21 17:03:37.750311199 -0700
@@ -435,18 +435,18 @@ coff_link_add_symbols (bfd *abfd,
if (obj_pe (abfd)
&& (classification == COFF_SYMBOL_GLOBAL
|| classification == COFF_SYMBOL_PE_SECTION)
- && section->comdat != NULL
+ && section->u.comdat != NULL
&& strncmp (name, "??_", 3) == 0
- && strcmp (name, section->comdat->name) == 0)
+ && strcmp (name, section->u.comdat->name) == 0)
{
if (*sym_hash == NULL)
*sym_hash = coff_link_hash_lookup (coff_hash_table (info),
name, FALSE, copy, FALSE);
if (*sym_hash != NULL
&& (*sym_hash)->root.type == bfd_link_hash_defined
- && (*sym_hash)->root.u.def.section->comdat != NULL
- && strcmp ((*sym_hash)->root.u.def.section->comdat->name,
- section->comdat->name) == 0)
+ && (*sym_hash)->root.u.def.section->u.comdat != NULL
+ && strcmp ((*sym_hash)->root.u.def.section->u.comdat->name,
+ section->u.comdat->name) == 0)
addit = FALSE;
}
--- binutils/bfd/ecoff.c.ident 2004-06-21 11:24:47.000000000 -0700
+++ binutils/bfd/ecoff.c 2004-06-21 17:03:37.754310681 -0700
@@ -93,8 +93,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-06-21 11:24:49.000000000 -0700
+++ binutils/bfd/elf-bfd.h 2004-06-21 17:03:37.757310292 -0700
@@ -1563,6 +1563,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-06-21 17:03:37.737312882 -0700
+++ binutils/bfd/elf.c 2004-06-21 17:03:37.762309645 -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-04-22 08:20:00.000000000 -0700
+++ binutils/bfd/elfcode.h 2004-06-21 17:03:37.765309257 -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-06-21 11:25:29.000000000 -0700
+++ binutils/bfd/elflink.c 2004-06-21 17:03:37.771308480 -0700
@@ -1862,7 +1862,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;
}
@@ -2052,7 +2053,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;
}
@@ -6080,8 +6081,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;
}
@@ -6599,7 +6600,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));
}
}
@@ -6638,7 +6639,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);
@@ -8578,7 +8579,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-06-21 11:25:52.000000000 -0700
+++ binutils/bfd/section.c 2004-06-21 17:03:37.774308092 -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
@@ -484,8 +500,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. *}
@@ -629,8 +650,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, \
@@ -1455,3 +1476,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-06-21 11:26:03.000000000 -0700
+++ binutils/binutils/objcopy.c 2004-06-21 17:03:37.777307703 -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-06-21 11:26:05.000000000 -0700
+++ binutils/binutils/objdump.c 2004-06-21 17:03:37.779307444 -0700
@@ -288,7 +288,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 = "";
@@ -352,9 +352,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-21 11:28:16.000000000 -0700
+++ binutils/ld/ldlang.c 2004-06-21 17:03:53.118321497 -0700
@@ -959,9 +959,10 @@ 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 (bfd_get_flavour (sec->owner) != bfd_target_coff_flavour
+ || sec->u.comdat == NULL
+ || l->sec->u.comdat == NULL
+ || 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 +975,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: