This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: [Patch] sh/sh64: Fix gotplt assertion failure
Nag hat: Could an SH maintainer please comment on this patch?
On Mon, Sep 16, 2002 at 06:06:13PM -0700, Clarke, Stephen wrote:
> This is a fix for a problem with the handling of
> SH_GOTPLTxxx relocations.
>
> The problem is with symbols that are forced local after
> the SH_GOTPLTxxx reloc handling in sh_elf_check_relocs has
> decided to use the plt... this leads to an assertion failure.
>
> The fix detects this situation in allocate_dynrelocs, and
> changes the plt references to be got references.
>
> Ld test included. Regression tested on sh64-elf/sh64-sim
> and sh-elf/sh-hms-sim.
>
> Steve.
> --
> Stephen Clarke, Principal Engineer, SuperH Inc.
> Phone:1-408-273-3146, Fax:1-408-273-3199, mailto:Stephen.Clarke@superh.com
> Mail: SuperH Inc., 405 River Oaks Pkwy, San Jose, CA 95134, USA.
Content-Description: gotplt-patch.txt
> bfd:
>
> 2002-09-16 Stephen Clarke <stephen.clarke@superh.com>
>
> * elf32-sh.c (elf_sh_link_hash_entry): Add gotplt_refcount.
> (sh_elf_link_hash_newfunc): Initialize it.
> (allocate_dynrelocs): Transfer gotplt refs from plt.refcount
> to got.refcount for symbols that are forced local or when
> we have direct got refs.
> (sh_elf_gc_sweep_hook): Adjust gotplt_refcount. Use it
> to correctly adjust got.refcount and plt.refcount.
> (sh_elf_copy_indirect_symbol): Copy gotplt_refcount across.
> (sh_elf_check_relocs): Increment gotplt_refcount.
>
> ld/testsuite:
>
> 2002-09-16 Stephen Clarke <stephen.clarke@superh.com>
>
> * ld-sh/sh64/gotplt.d, ld-sh/sh64/gotplt.map,
> ld-sh/sh64/gotplt.s: New test.
>
> Index: bfd/elf32-sh.c
> ===================================================================
> RCS file: /cvs/src/src/bfd/elf32-sh.c,v
> retrieving revision 1.58
> diff -u -c -3 -p -r1.58 elf32-sh.c
> *** bfd/elf32-sh.c 24 Aug 2002 01:44:56 -0000 1.58
> --- bfd/elf32-sh.c 16 Sep 2002 20:54:49 -0000
> *************** struct elf_sh_link_hash_entry
> *** 3388,3393 ****
> --- 3388,3395 ----
>
> /* Track dynamic relocs copied for this symbol. */
> struct elf_sh_dyn_relocs *dyn_relocs;
> +
> + bfd_signed_vma gotplt_refcount;
> };
>
> /* sh ELF linker hash table. */
> *************** sh_elf_link_hash_newfunc (entry, table,
> *** 3452,3457 ****
> --- 3454,3460 ----
>
> eh = (struct elf_sh_link_hash_entry *) ret;
> eh->dyn_relocs = NULL;
> + eh->gotplt_refcount = 0;
> #ifdef INCLUDE_SHMEDIA
> ret->datalabel_got_offset = (bfd_vma) -1;
> #endif
> *************** allocate_dynrelocs (h, inf)
> *** 3867,3872 ****
> --- 3870,3887 ----
> info = (struct bfd_link_info *) inf;
> htab = sh_elf_hash_table (info);
>
> + eh = (struct elf_sh_link_hash_entry *) h;
> + if ((h->got.refcount > 0
> + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
> + && eh->gotplt_refcount > 0)
> + {
> + /* The symbol has been forced local, or we have some direct got refs,
> + so treat all the gotplt refs as got refs. */
> + h->got.refcount += eh->gotplt_refcount;
> + if (h->plt.refcount >= eh->gotplt_refcount)
> + h->plt.refcount -= eh->gotplt_refcount;
> + }
> +
> if (htab->root.dynamic_sections_created
> && h->plt.refcount > 0)
> {
> *************** allocate_dynrelocs (h, inf)
> *** 3961,3967 ****
> else
> h->got.offset = (bfd_vma) -1;
>
> - eh = (struct elf_sh_link_hash_entry *) h;
> if (eh->dyn_relocs == NULL)
> return true;
>
> --- 3976,3981 ----
> *************** sh_elf_gc_sweep_hook (abfd, info, sec, r
> *** 5200,5205 ****
> --- 5214,5220 ----
> const Elf_Internal_Rela *rel, *relend;
> unsigned long r_symndx;
> struct elf_link_hash_entry *h;
> + struct elf_sh_link_hash_entry *eh;
>
> elf_section_data (sec)->local_dynrel = NULL;
>
> *************** sh_elf_gc_sweep_hook (abfd, info, sec, r
> *** 5302,5311 ****
> if (r_symndx >= symtab_hdr->sh_info)
> {
> h = sym_hashes[r_symndx - symtab_hdr->sh_info];
> ! if (h->got.refcount > 0)
> h->got.refcount -= 1;
> - if (h->plt.refcount > 0)
> - h->plt.refcount -= 1;
> }
> else if (local_got_refcounts != NULL)
> {
> --- 5317,5331 ----
> if (r_symndx >= symtab_hdr->sh_info)
> {
> h = sym_hashes[r_symndx - symtab_hdr->sh_info];
> ! eh = (struct elf_sh_link_hash_entry *) h;
> ! if (eh->gotplt_refcount > 0)
> ! {
> ! eh->gotplt_refcount -= 1;
> ! if (h->plt.refcount > 0)
> ! h->plt.refcount -= 1;
> ! }
> ! else if (h->got.refcount > 0)
> h->got.refcount -= 1;
> }
> else if (local_got_refcounts != NULL)
> {
> *************** sh_elf_copy_indirect_symbol (bed, dir, i
> *** 5365,5370 ****
> --- 5385,5392 ----
> edir->dyn_relocs = eind->dyn_relocs;
> eind->dyn_relocs = NULL;
> }
> + edir->gotplt_refcount = eind->gotplt_refcount;
> + eind->gotplt_refcount = 0;
>
> _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
> }
> *************** sh_elf_check_relocs (abfd, info, sec, re
> *** 5539,5544 ****
> --- 5561,5567 ----
>
> h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
> h->plt.refcount += 1;
> + ((struct elf_sh_link_hash_entry *) h)->gotplt_refcount += 1;
>
> break;
>
> Index: ld/testsuite/ld-sh/sh64/gotplt.d
> ===================================================================
> RCS file: ld/testsuite/ld-sh/sh64/gotplt.d
> diff -N ld/testsuite/ld-sh/sh64/gotplt.d
> *** /dev/null 1 Jan 1970 00:00:00 -0000
> --- ld/testsuite/ld-sh/sh64/gotplt.d 16 Sep 2002 20:54:52 -0000
> ***************
> *** 0 ****
> --- 1,12 ----
> + #source: gotplt.s
> + #as: --abi=32 --isa=SHmedia
> + #ld: -shared -mshelf32 --version-script=$srcdir/$subdir/gotplt.map
> + #readelf: -r
> + #target: sh64-*-elf
> +
> + # Make sure that gotplt relocations of forced local symbols
> + # use the GOT.
> +
> + Relocation section '\.rela\.dyn' at offset 0x3fc contains 1 entries:
> + Offset Info Type Sym\.Value Sym\. Name \+ Addend
> + 0000052c 000000a5 R_SH_RELATIVE 00000408
> Index: ld/testsuite/ld-sh/sh64/gotplt.map
> ===================================================================
> RCS file: ld/testsuite/ld-sh/sh64/gotplt.map
> diff -N ld/testsuite/ld-sh/sh64/gotplt.map
> *** /dev/null 1 Jan 1970 00:00:00 -0000
> --- ld/testsuite/ld-sh/sh64/gotplt.map 16 Sep 2002 20:54:52 -0000
> ***************
> *** 0 ****
> --- 1,4 ----
> + GLIBC_2.2 {
> + local:
> + xxx;
> + };
> Index: ld/testsuite/ld-sh/sh64/gotplt.s
> ===================================================================
> RCS file: ld/testsuite/ld-sh/sh64/gotplt.s
> diff -N ld/testsuite/ld-sh/sh64/gotplt.s
> *** /dev/null 1 Jan 1970 00:00:00 -0000
> --- ld/testsuite/ld-sh/sh64/gotplt.s 16 Sep 2002 20:54:52 -0000
> ***************
> *** 0 ****
> --- 1,8 ----
> + .text
> + .global xxx
> + xxx:
> + ptabs r18, tr0
> + blink tr0, r63
> + .global yyy
> + yyy:
> + movi ((xxx@GOTPLT) & 65535), r1
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer