This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: PR ld/6931: COMDAT group is broken
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: "H.J. Lu" <hjl dot tools at gmail dot com>
- Cc: binutils at sources dot redhat dot com, amodra at bigpond dot net dot au
- Date: Thu, 2 Oct 2008 17:29:28 -0700
- Subject: Re: PATCH: PR ld/6931: COMDAT group is broken
- References: <20081002214244.GA28256@lucon.org>
It doesn't work on
[hjl@gnu-6 ld]$ cat /tmp/group-4.s
.section .text.foo4,"axG",%progbits,foo4,comdat
foo4:
.word 0
.section .data.foo4,"awG",%progbits,foo4,comdat
bar4:
.word 0
[hjl@gnu-6 ld]$ gcc -c /tmp/group-4.s
[hjl@gnu-6 ld]$ ./ld-new -r group-4.o
[hjl@gnu-6 ld]$ readelf -Sg a.out
There are 10 section headers, starting at offset 0xa0:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .group GROUP 0000000000000000 00000040
000000000000000c 0000000000000004 8 8 4
[ 2] .text PROGBITS 0000000000000000 0000004c
0000000000000000 0000000000000000 AX 0 0 4
[ 3] .text.foo4 PROGBITS 0000000000000000 0000004c
0000000000000002 0000000000000000 AXG 0 0 1
[ 4] .data PROGBITS 0000000000000000 00000050
0000000000000000 0000000000000000 WA 0 0 4
[ 5] .data.foo4 PROGBITS 0000000000000000 00000050
0000000000000002 0000000000000000 WAG 0 0 1
[ 6] .bss NOBITS 0000000000000000 00000054
0000000000000000 0000000000000000 WA 0 0 4
[ 7] .shstrtab STRTAB 0000000000000000 00000054
0000000000000049 0000000000000000 0 0 1
[ 8] .symtab SYMTAB 0000000000000000 00000320
00000000000000d8 0000000000000018 9 9 8
[ 9] .strtab STRTAB 0000000000000000 000003f8
000000000000000b 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
COMDAT group section [ 1] `.group' [bar4] contains 2 sections:
[Index] Name
[ 3] .text.foo4
[ 5] .data.foo4
[hjl@gnu-6 ld]$
H.J.
On Thu, Oct 2, 2008 at 2:42 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> bfd_elf_set_group_contents needs to handle group signature properly for
> ld -r. The sh_info field of group section has the symbol table index
> of group signature. We need to get the symbol table index of group
> signature in output file. We start with the symbol table index for
> group signature in input file. If it is a global symbol, we can get
> its index from ELF symbol hash table. If it is a local symbol, we
> have to first get the symbol table entry for group signature in
> input file and then compute the symbol table index in output file.
>
> OK to install?
>
>
> H.J.
> --
> bfd/
>
> 2008-10-02 H.J. Lu <hongjiu.lu@intel.com>
>
> PR ld/6931
> * elf.c (bfd_elf_set_group_contents): Properly get the symbol
> table index for group signature for ld -r.
>
> ld/testsuite/
>
> 2008-10-02 H.J. Lu <hongjiu.lu@intel.com>
>
> PR ld/6931
> * ld-elf/group4.d: New.
> * ld-elf/group5.d: Likewise.
> * ld-elf/group6.d: Likewise.
>
> --- binutils/bfd/elf.c.grp 2008-10-02 13:52:45.000000000 -0700
> +++ binutils/bfd/elf.c 2008-10-02 14:00:14.000000000 -0700
> @@ -2715,11 +2715,73 @@ bfd_elf_set_group_contents (bfd *abfd, a
> 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. */
> + elf_section_syms. */
> if (elf_section_syms (abfd) != NULL)
> symindx = elf_section_syms (abfd)[sec->index]->udata.i;
> else
> - symindx = sec->target_index;
> + {
> + struct bfd_link_order *lo;
> + asection *input;
> + Elf_Internal_Shdr *symtab_hdr;
> +
> + /* Handle "ld -r". */
> + input = NULL;
> + for (lo = sec->map_head.link_order; lo != NULL; lo = lo->next)
> + if (lo->type == bfd_indirect_link_order)
> + {
> + /* There should be only one input section. */
> + BFD_ASSERT (input == NULL);
> +
> + input = lo->u.indirect.section;
> + /* Get the symbol table index for group signature in
> + input file. */
> + symindx = elf_section_data(input)->this_hdr.sh_info;
> + }
> +
> + BFD_ASSERT (input != NULL);
> +
> + symtab_hdr = &elf_symtab_hdr (input->owner);
> + if (symindx < symtab_hdr->sh_info)
> + {
> + unsigned char esym[sizeof (Elf64_External_Sym)];
> + Elf_External_Sym_Shndx eshndx;
> + Elf_Internal_Sym isym;
> + Elf_Internal_Shdr *elf_sect;
> + int target_index;
> +
> + /* Get the symbol table entry for group signature in
> + input file. */
> + if (bfd_elf_get_elf_syms (input->owner, symtab_hdr, 1,
> + symindx, &isym, esym, &eshndx)
> + == NULL)
> + abort ();
> +
> + /* Get the group signature section in input file. */
> + elf_sect = elf_elfsections (input->owner)[isym.st_shndx];
> +
> + /* Compute the symbol table index for group signature
> + in output file. */
> + target_index
> + = elf_sect->bfd_section->output_section->target_index;
> + if (ELF_ST_TYPE (isym.st_info) == STT_SECTION)
> + symindx = target_index;
> + else
> + symindx += target_index;
> + }
> + else
> + {
> + struct elf_link_hash_entry **sym_hashes;
> + struct elf_link_hash_entry *h;
> +
> + sym_hashes = elf_sym_hashes (input->owner);
> + h = sym_hashes[symindx - symtab_hdr->sh_info];
> + while (h->root.type == bfd_link_hash_indirect
> + || h->root.type == bfd_link_hash_warning)
> + h = (struct elf_link_hash_entry *) h->root.u.i.link;
> + symindx = h->indx;
> + }
> + }
> + BFD_ASSERT (symindx != 0);
> }
> elf_section_data (sec)->this_hdr.sh_info = symindx;
>
> --- binutils/ld/testsuite/ld-elf/group4.d.grp 2008-10-02 13:52:46.000000000 -0700
> +++ binutils/ld/testsuite/ld-elf/group4.d 2008-10-02 13:52:46.000000000 -0700
> @@ -0,0 +1,16 @@
> +#source: ../../../binutils/testsuite/binutils-all/group-2.s
> +#ld: -r
> +#readelf: -Sg --wide
> +
> +#...
> + \[[ 0-9]+\] .group[ \t]+GROUP[ \t]+.*
> +#...
> + \[[ 0-9]+\] \.text.*[ \t]+PROGBITS[ \t0-9a-f]+AXG[ \t]+.*
> +#...
> + \[[ 0-9]+\] \.data.*[ \t]+PROGBITS[ \t0-9a-f]+WAG[ \t]+.*
> +#...
> +COMDAT group section \[[ 0-9]+\] `.group' \[.text.foo\] contains 2 sections:
> + \[Index\] Name
> + \[[ 0-9]+\] .text.*
> + \[[ 0-9]+\] .data.*
> +#pass
> --- binutils/ld/testsuite/ld-elf/group5.d.grp 2008-10-02 13:52:46.000000000 -0700
> +++ binutils/ld/testsuite/ld-elf/group5.d 2008-10-02 13:52:46.000000000 -0700
> @@ -0,0 +1,16 @@
> +#source: ../../../binutils/testsuite/binutils-all/group-3.s
> +#ld: -r
> +#readelf: -Sg --wide
> +
> +#...
> + \[[ 0-9]+\] .group[ \t]+GROUP[ \t]+.*
> +#...
> + \[[ 0-9]+\] \.text.*[ \t]+PROGBITS[ \t0-9a-f]+AXG[ \t]+.*
> +#...
> + \[[ 0-9]+\] \.data.*[ \t]+PROGBITS[ \t0-9a-f]+WAG[ \t]+.*
> +#...
> +COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains 2 sections:
> + \[Index\] Name
> + \[[ 0-9]+\] .text.*
> + \[[ 0-9]+\] .data.*
> +#pass
> --- binutils/ld/testsuite/ld-elf/group6.d.grp 2008-10-02 13:52:46.000000000 -0700
> +++ binutils/ld/testsuite/ld-elf/group6.d 2008-10-02 13:52:46.000000000 -0700
> @@ -0,0 +1,16 @@
> +#source: ../../../binutils/testsuite/binutils-all/group-4.s
> +#ld: -r
> +#readelf: -Sg --wide
> +
> +#...
> + \[[ 0-9]+\] .group[ \t]+GROUP[ \t]+.*
> +#...
> + \[[ 0-9]+\] \.text.*[ \t]+PROGBITS[ \t0-9a-f]+AXG[ \t]+.*
> +#...
> + \[[ 0-9]+\] \.data.*[ \t]+PROGBITS[ \t0-9a-f]+WAG[ \t]+.*
> +#...
> +COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains 2 sections:
> + \[Index\] Name
> + \[[ 0-9]+\] .text.*
> + \[[ 0-9]+\] .data.*
> +#pass
>
--
H.J.