This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]