This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
RE: Group identifier of a comdat group
- From: "Jessica Han" <jessica at cup dot hp dot com>
- To: "'Alan Modra'" <amodra at bigpond dot net dot au>,<binutils at sources dot redhat dot com>, <reva at cup dot hp dot com>
- Date: Wed, 5 Jun 2002 15:01:10 -0700
- Subject: RE: Group identifier of a comdat group
- Reply-to: <jessica at cup dot hp dot com>
I noticed that the change you made is in the group_signature, which is
trying to retrieve the group signature information used by objcopy and ld.
Is it possible to change the gas behavior, put the section names into
symtab/strtab directly? thanks.
>-----Original Message-----
>From: Alan Modra [mailto:amodra@bigpond.net.au]
>Sent: Wednesday, June 05, 2002 7:04 AM
>To: Jessica Han; binutils@sources.redhat.com; reva@cup.hp.com
>Subject: Re: Group identifier of a comdat group
>
>
>On Wed, Jun 05, 2002 at 10:39:00AM +0930, Alan Modra wrote:
>> Sounds like a problem in the object file itself.
>
>Problem is with the author of this code (ie. me). This fixes the
>symbol problem (which I wasn't seeing due to using .group as the
>section name for all SHT_GROUP sections in my local copy of gas).
>Also makes objcopy and ld -r work, at least with my simple testcases.
>
>bfd/ChangeLog
> * elf.c (group_signature): Swap in the whole symbol, and handle
> extracting section symbol names.
> (setup_group): Add comment.
> (set_group_contents): When called from objcopy or ld,
>arrange for
> section contents to be written. Write group member
>output section
> indices to allow objcopy to reorganize sections.
> (_bfd_elf_copy_private_section_data): Copy group info.
>
>binutils/ChangeLog
> * objcopy.c (copy_section): Don't copy SEC_GROUP sections.
>
>ld/ChangeLog
> * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Place
> SEC_EXCLUDE sections when doing a relocatable link.
>
>Index: bfd/elf.c
>===================================================================
>RCS file: /cvs/src/src/bfd/elf.c,v
>retrieving revision 1.143
>diff -u -p -r1.143 elf.c
>--- bfd/elf.c 5 Jun 2002 03:43:09 -0000 1.143
>+++ bfd/elf.c 5 Jun 2002 14:00:26 -0000
>@@ -372,23 +372,54 @@ group_signature (abfd, ghdr)
> {
> struct elf_backend_data *bed;
> file_ptr pos;
>- unsigned char ename[4];
>- unsigned long iname;
>+ bfd_size_type amt;
>+ Elf_Internal_Shdr *hdr;
>+ Elf_Internal_Shdr *shndx_hdr;
>+ unsigned char esym[sizeof (Elf64_External_Sym)];
>+ Elf_External_Sym_Shndx eshndx;
>+ Elf_Internal_Sym isym;
>+ unsigned int iname;
>+ unsigned int shindex;
>
> /* First we need to ensure the symbol table is available. */
> if (! bfd_section_from_shdr (abfd, ghdr->sh_link))
> return NULL;
>
>- /* Fortunately, the name index is at the same place in the external
>- symbol for both 32 and 64 bit ELF. */
>+ /* Go read the symbol. */
>+ hdr = &elf_tdata (abfd)->symtab_hdr;
> bed = get_elf_backend_data (abfd);
>- pos = elf_tdata (abfd)->symtab_hdr.sh_offset;
>- pos += ghdr->sh_info * bed->s->sizeof_sym;
>+ amt = bed->s->sizeof_sym;
>+ pos = hdr->sh_offset + ghdr->sh_info * amt;
> if (bfd_seek (abfd, pos, SEEK_SET) != 0
>- || bfd_bread (ename, (bfd_size_type) 4, abfd) != 4)
>+ || bfd_bread (esym, amt, abfd) != amt)
> return NULL;
>- iname = H_GET_32 (abfd, ename);
>- return elf_string_from_elf_strtab (abfd, iname);
>+
>+ /* And possibly the symbol section index extension. */
>+ shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
>+ if (elf_elfsections (abfd) != NULL
>+ && elf_elfsections (abfd)[shndx_hdr->sh_link] == hdr)
>+ {
>+ amt = sizeof (Elf_External_Sym_Shndx);
>+ pos = shndx_hdr->sh_offset + ghdr->sh_info * amt;
>+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
>+ || bfd_bread ((PTR) &eshndx, amt, abfd) != amt)
>+ return NULL;
>+ }
>+
>+ /* Convert to internal format. */
>+ (*bed->s->swap_symbol_in) (abfd, (const PTR *) &esym,
>(const PTR *) &eshndx,
>+ &isym);
>+
>+ /* Look up the symbol name. */
>+ iname = isym.st_name;
>+ shindex = hdr->sh_link;
>+ if (iname == 0 && ELF_ST_TYPE (isym.st_info) == STT_SECTION)
>+ {
>+ iname = elf_elfsections (abfd)[isym.st_shndx]->sh_name;
>+ shindex = elf_elfheader (abfd)->e_shstrndx;
>+ }
>+
>+ return bfd_elf_string_from_elf_section (abfd, shindex, iname);
> }
>
> /* Set next_in_group list pointer, and group name for NEWSECT. */
>@@ -536,6 +567,8 @@ setup_group (abfd, hdr, newsect)
> elf_next_in_group (newsect) = newsect;
> }
>
>+ /* If the group section has been created, point to the
>+ new member. */
> if (shdr->bfd_section != NULL)
> elf_next_in_group (shdr->bfd_section) = newsect;
>
>@@ -2357,9 +2390,10 @@ set_group_contents (abfd, sec, failedptr
> {
> boolean *failedptr = (boolean *) failedptrarg;
> unsigned long symindx;
>- asection *elt;
>+ asection *elt, *first;
> unsigned char *loc;
> struct bfd_link_order *l;
>+ boolean gas;
>
> if (elf_section_data (sec)->this_hdr.sh_type != SHT_GROUP
> || *failedptr)
>@@ -2374,10 +2408,15 @@ set_group_contents (abfd, sec, failedptr
> symindx = elf_section_data (sec)->this_idx;
> elf_section_data (sec)->this_hdr.sh_info = symindx;
>
>- /* Nor will the contents be allocated for "ld -r". */
>+ /* Nor will the contents be allocated for "ld -r" or objcopy. */
>+ gas = true;
> if (sec->contents == NULL)
> {
>+ gas = false;
> sec->contents = bfd_alloc (abfd, sec->_raw_size);
>+
>+ /* Arrange for the section to be written out. */
>+ elf_section_data (sec)->this_hdr.contents = sec->contents;
> if (sec->contents == NULL)
> {
> *failedptr = true;
>@@ -2387,9 +2426,10 @@ set_group_contents (abfd, sec, failedptr
>
> loc = sec->contents + sec->_raw_size;
>
>- /* Get the pointer to the first section in the group that we
>- squirreled away here. */
>- elt = elf_next_in_group (sec);
>+ /* Get the pointer to the first section in the group that gas
>+ squirreled away here. objcopy arranges for this to be set to the
>+ start of the input section group. */
>+ first = elt = elf_next_in_group (sec);
>
> /* First element is a flag word. Rest of section is elf section
> indices for all the sections of the group. Write them backwards
>@@ -2397,9 +2437,20 @@ set_group_contents (abfd, sec, failedptr
> directives, not that it matters. */
> while (elt != NULL)
> {
>+ asection *s;
>+ unsigned int idx;
>+
> loc -= 4;
>- H_PUT_32 (abfd, elf_section_data (elt)->this_idx, loc);
>+ s = elt;
>+ if (!gas)
>+ s = s->output_section;
>+ idx = 0;
>+ if (s != NULL)
>+ idx = elf_section_data (s)->this_idx;
>+ H_PUT_32 (abfd, idx, loc);
> elt = elf_next_in_group (elt);
>+ if (elt == first)
>+ break;
> }
>
> /* If this is a relocatable link, then the above did nothing because
>@@ -2418,10 +2469,16 @@ set_group_contents (abfd, sec, failedptr
> }
> while (elt != elf_next_in_group (l->u.indirect.section));
>
>- loc -= 4;
>- H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
>+ /* With ld -r, merging SHT_GROUP sections results in wasted space
>+ due to allowing for the flag word on each input. We may well
>+ duplicate entries too. */
>+ while ((loc -= 4) > sec->contents)
>+ H_PUT_32 (abfd, 0, loc);
>+
>+ if (loc != sec->contents)
>+ abort ();
>
>- BFD_ASSERT (loc == sec->contents);
>+ H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
> }
>
> /* Assign all ELF section numbers. The dummy first section
>is handled here
>@@ -4940,6 +4997,12 @@ _bfd_elf_copy_private_section_data (ibfd
> || ihdr->sh_type == SHT_GNU_verneed
> || 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. */
>+ elf_next_in_group (osec) = elf_next_in_group (isec);
>+ elf_group_name (osec) = elf_group_name (isec);
>
> elf_section_data (osec)->use_rela_p
> = elf_section_data (isec)->use_rela_p;
>Index: binutils/objcopy.c
>===================================================================
>RCS file: /cvs/src/src/binutils/objcopy.c,v
>retrieving revision 1.39
>diff -u -p -r1.39 objcopy.c
>--- binutils/objcopy.c 21 May 2002 19:34:58 -0000 1.39
>+++ binutils/objcopy.c 5 Jun 2002 13:40:33 -0000
>@@ -1684,18 +1684,23 @@ copy_section (ibfd, isection, obfdarg)
> sec_ptr osection;
> bfd_size_type size;
> long relsize;
>+ flagword flags;
>
> /* If we have already failed earlier on,
> do not keep on generating complaints now. */
> if (status != 0)
> return;
>
>- if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
>+ flags = bfd_get_section_flags (ibfd, isection);
>+ if ((flags & SEC_DEBUGGING) != 0
> && (strip_symbols == STRIP_DEBUG
> || strip_symbols == STRIP_UNNEEDED
> || strip_symbols == STRIP_ALL
> || discard_locals == LOCALS_ALL
> || convert_debugging))
>+ return;
>+
>+ if ((flags & SEC_GROUP) != 0)
> return;
>
> p = find_section_list (bfd_section_name (ibfd, isection), false);
>Index: ld/emultempl/elf32.em
>===================================================================
>RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
>retrieving revision 1.76
>diff -u -p -r1.76 elf32.em
>--- ld/emultempl/elf32.em 27 May 2002 08:22:08 -0000 1.76
>+++ ld/emultempl/elf32.em 5 Jun 2002 14:00:27 -0000
>@@ -1107,7 +1107,7 @@ gld${EMULATION_NAME}_place_orphan (file,
> #define HAVE_SECTION(hold, name) \
> (hold.os != NULL || (hold.os = lang_output_section_find
>(name)) != NULL)
>
>- if (s->flags & SEC_EXCLUDE)
>+ if ((s->flags & SEC_EXCLUDE) != 0 && !link_info.relocateable)
> {
> if (s->output_section == NULL)
> s->output_section = bfd_abs_section_ptr;
>
>--
>Alan Modra
>IBM OzLabs - Linux Technology Centre
>