public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* RE: [Patch] sh64: Fix refcounting for SHmedia
@ 2002-10-11 13:04 Clarke, Stephen
  2002-10-13 22:11 ` Hans-Peter Nilsson
  0 siblings, 1 reply; 4+ messages in thread
From: Clarke, Stephen @ 2002-10-11 13:04 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 870 bytes --]

> From: Alan Modra
> Sent: Friday, October 11, 2002 2:34 AM
> On Thu, Oct 10, 2002 at 04:58:23PM -0700, Clarke, Stephen wrote:
> > *************** sh_elf_link_hash_newfunc (entry, table, 
> [...]
> You should get rid of "eh" here as "ret" and "eh" have the same type.
> Also, avoid a cast by writing
> 
>       ret->datalabel_got.refcount = ret->root.got.refcount;
> 
> Other than that, the patch looks good to me.

Here's the revised patch.  I've cleaned up
sh_elf_link_hash_newfunc as requested, and remade the whole patch
now that the tls support has been merged in.

The code in allocate_dynrelocs and sh_elf_finish_dynamic_symbol will
almost certainly require extra work when tls is extended to sh64, but
I've treated that as out of the scope of this patch - it requires an
understanding of the interraction between datalabel and tls.

Steve.

[-- Attachment #2: datalabel-got-patch.gz --]
[-- Type: application/x-gzip, Size: 3907 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [Patch] sh64: Fix refcounting for SHmedia
  2002-10-11 13:04 [Patch] sh64: Fix refcounting for SHmedia Clarke, Stephen
@ 2002-10-13 22:11 ` Hans-Peter Nilsson
  0 siblings, 0 replies; 4+ messages in thread
From: Hans-Peter Nilsson @ 2002-10-13 22:11 UTC (permalink / raw)
  To: Clarke, Stephen; +Cc: binutils

On Fri, 11 Oct 2002, Clarke, Stephen wrote:
> Here's the revised patch.  I've cleaned up
> sh_elf_link_hash_newfunc as requested, and remade the whole patch
> now that the tls support has been merged in.

Ok.  I recall you mentioned Kaz Kojima wrote parts of this?
If so, consider adding him as co-author in the ChangeLog entry.

brgds, H-P

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Patch] sh64: Fix refcounting for SHmedia
  2002-10-10 16:59 Clarke, Stephen
@ 2002-10-11  2:33 ` Alan Modra
  0 siblings, 0 replies; 4+ messages in thread
From: Alan Modra @ 2002-10-11  2:33 UTC (permalink / raw)
  To: Clarke, Stephen; +Cc: binutils

On Thu, Oct 10, 2002 at 04:58:23PM -0700, Clarke, Stephen wrote:
> *************** sh_elf_link_hash_newfunc (entry, table, 
> *** 3456,3462 ****
>         eh->dyn_relocs = NULL;
>         eh->gotplt_refcount = 0;
>   #ifdef INCLUDE_SHMEDIA
> !       ret->datalabel_got_offset = (bfd_vma) -1;
>   #endif
>       }
>   
> --- 3460,3467 ----
>         eh->dyn_relocs = NULL;
>         eh->gotplt_refcount = 0;
>   #ifdef INCLUDE_SHMEDIA
> !       eh->datalabel_got.refcount =
> ! 	((struct elf_link_hash_entry *) ret)->got.refcount;
>   #endif
>       }
>   

You should get rid of "eh" here as "ret" and "eh" have the same type.
Also, avoid a cast by writing

      ret->datalabel_got.refcount = ret->root.got.refcount;

Other than that, the patch looks good to me.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Patch] sh64: Fix refcounting for SHmedia
@ 2002-10-10 16:59 Clarke, Stephen
  2002-10-11  2:33 ` Alan Modra
  0 siblings, 1 reply; 4+ messages in thread
From: Clarke, Stephen @ 2002-10-10 16:59 UTC (permalink / raw)
  To: binutils; +Cc: amodra

[-- Attachment #1: Type: text/plain, Size: 618 bytes --]

Back in August I promised to work on the required
fixes to refcounting for sh64 in the sh elf backend.
I've finally got these implemented and tested them
by building and using glibc (.so) on SH-5 Linux.

The attached file contains the patch, it follows
fairly closely what I speculatively outlined in:
http://sources.redhat.com/ml/binutils/2002-07/msg00190.html

This patch is for the 32-bit abi only.

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.

[-- Attachment #2: datalabel-got-patch.txt --]
[-- Type: text/plain, Size: 17076 bytes --]

2002-10-10  Stephen Clarke <stephen.clarke@superh.com>

	* elf32-sh.c (elf_sh_link_hash_entry): Replace
	datalabel_got_offset with union of datalabel_got
	offset and refcount.
	(sh_elf_link_hash_newfunc): Initialize datalabel_got.refcount.
	(allocate_dynrelocs): Delete unnecessary code for
	STT_DATALABEL type.  Create entry in got for
	datalabel version of symbol if datalabel_got.refcount > 0.
	(sh_elf_relocate_section): Use datalabel_got union.
	(sh_elf_gc_sweep_hook): Pull common code to initialize
	h and eh out of switch statement.  Declare seen_stt_datalabel.
	Initialize it.  Decrement datalabel_got.refcount for
	got relocs when seen_stt_datalabel is true.
	Decrement local_got_refcounts entry for datalabel got relocs
	of local symbols.
	(sh_elf_copy_indirect_symbol): Copy datalabel_got field over.
	(sh_elf_check_relocs): Declare seen_stt_datalabel.
	Initialize it.  When seen_stt_datalabel is true, increment
	datalabel_got refcount rather than got.refcount.
	(sh_elf_finish_dynamic_symbol): Create relocs to
	initialize got entry for datalabel version of symbol.

Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.60
diff -u -c -3 -p -r1.60 elf32-sh.c
*** bfd/elf32-sh.c	10 Oct 2002 21:45:14 -0000	1.60
--- bfd/elf32-sh.c	10 Oct 2002 23:24:30 -0000
*************** struct elf_sh_link_hash_entry
*** 3383,3389 ****
    struct elf_link_hash_entry root;
  
  #ifdef INCLUDE_SHMEDIA
!   bfd_vma datalabel_got_offset;
  #endif
  
    /* Track dynamic relocs copied for this symbol.  */
--- 3383,3393 ----
    struct elf_link_hash_entry root;
  
  #ifdef INCLUDE_SHMEDIA
!   union
!   {
!     bfd_signed_vma refcount;
!     bfd_vma offset;
!   } datalabel_got;
  #endif
  
    /* Track dynamic relocs copied for this symbol.  */
*************** sh_elf_link_hash_newfunc (entry, table, 
*** 3456,3462 ****
        eh->dyn_relocs = NULL;
        eh->gotplt_refcount = 0;
  #ifdef INCLUDE_SHMEDIA
!       ret->datalabel_got_offset = (bfd_vma) -1;
  #endif
      }
  
--- 3460,3467 ----
        eh->dyn_relocs = NULL;
        eh->gotplt_refcount = 0;
  #ifdef INCLUDE_SHMEDIA
!       eh->datalabel_got.refcount =
! 	((struct elf_link_hash_entry *) ret)->got.refcount;
  #endif
      }
  
*************** allocate_dynrelocs (h, inf)
*** 3954,3980 ****
  	}
  
        s = htab->sgot;
  #ifdef INCLUDE_SHMEDIA
!       if (h->type == STT_DATALABEL)
! 	{
! 	  struct elf_sh_link_hash_entry *hsh;
  
! 	  h = (struct elf_link_hash_entry *) h->root.u.i.link;
! 	  hsh = (struct elf_sh_link_hash_entry *)h;
! 	  hsh->datalabel_got_offset = s->_raw_size;
  	}
!       else
! 	h->got.offset = s->_raw_size;
! #else
!       h->got.offset = s->_raw_size;
! #endif
        s->_raw_size += 4;
        dyn = htab->root.dynamic_sections_created;
        if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
  	htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
      }
    else
!     h->got.offset = (bfd_vma) -1;
  
    if (eh->dyn_relocs == NULL)
      return true;
--- 3959,3998 ----
  	}
  
        s = htab->sgot;
+       h->got.offset = s->_raw_size;
+       s->_raw_size += 4;
+       dyn = htab->root.dynamic_sections_created;
+       if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
+ 	htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
+     }
+   else
+     h->got.offset = (bfd_vma) -1;
+ 
  #ifdef INCLUDE_SHMEDIA
!   if (eh->datalabel_got.refcount > 0)
!     {
!       asection *s;
!       boolean dyn;
  
!       /* Make sure this symbol is output as a dynamic symbol.
! 	 Undefined weak syms won't yet be marked as dynamic.  */
!       if (h->dynindx == -1
! 	  && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
! 	{
! 	  if (! bfd_elf32_link_record_dynamic_symbol (info, h))
! 	    return false;
  	}
! 
!       s = htab->sgot;
!       eh->datalabel_got.offset = s->_raw_size;
        s->_raw_size += 4;
        dyn = htab->root.dynamic_sections_created;
        if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
  	htab->srelgot->_raw_size += sizeof (Elf32_External_Rela);
      }
    else
!     eh->datalabel_got.offset = (bfd_vma) -1;
! #endif
  
    if (eh->dyn_relocs == NULL)
      return true;
*************** sh_elf_relocate_section (output_bfd, inf
*** 4789,4795 ****
  		  struct elf_sh_link_hash_entry *hsh;
  
  		  hsh = (struct elf_sh_link_hash_entry *)h;
! 		  off = hsh->datalabel_got_offset;
  		}
  #endif
  	      BFD_ASSERT (off != (bfd_vma) -1);
--- 4807,4813 ----
  		  struct elf_sh_link_hash_entry *hsh;
  
  		  hsh = (struct elf_sh_link_hash_entry *)h;
! 		  off = hsh->datalabel_got.offset;
  		}
  #endif
  	      BFD_ASSERT (off != (bfd_vma) -1);
*************** sh_elf_relocate_section (output_bfd, inf
*** 4825,4831 ****
  			  struct elf_sh_link_hash_entry *hsh;
  
  			  hsh = (struct elf_sh_link_hash_entry *)h;
! 			  hsh->datalabel_got_offset |= 1;
  			}
  		      else
  #endif
--- 4843,4849 ----
  			  struct elf_sh_link_hash_entry *hsh;
  
  			  hsh = (struct elf_sh_link_hash_entry *)h;
! 			  hsh->datalabel_got.offset |= 1;
  			}
  		      else
  #endif
*************** sh_elf_gc_sweep_hook (abfd, info, sec, r
*** 5224,5342 ****
  
    relend = relocs + sec->reloc_count;
    for (rel = relocs; rel < relend; rel++)
!     switch (ELF32_R_TYPE (rel->r_info))
!       {
!       case R_SH_GOT32:
!       case R_SH_GOTOFF:
!       case R_SH_GOTPC:
! #ifdef INCLUDE_SHMEDIA
!       case R_SH_GOT_LOW16:
!       case R_SH_GOT_MEDLOW16:
!       case R_SH_GOT_MEDHI16:
!       case R_SH_GOT_HI16:
!       case R_SH_GOT10BY4:
!       case R_SH_GOT10BY8:
!       case R_SH_GOTOFF_LOW16:
!       case R_SH_GOTOFF_MEDLOW16:
!       case R_SH_GOTOFF_MEDHI16:
!       case R_SH_GOTOFF_HI16:
!       case R_SH_GOTPC_LOW16:
!       case R_SH_GOTPC_MEDLOW16:
!       case R_SH_GOTPC_MEDHI16:
!       case R_SH_GOTPC_HI16:
  #endif
- 	r_symndx = ELF32_R_SYM (rel->r_info);
- 	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;
- 	  }
- 	else if (local_got_refcounts != NULL)
- 	  {
- 	    if (local_got_refcounts[r_symndx] > 0)
- 	      local_got_refcounts[r_symndx] -= 1;
- 	  }
- 	break;
  
!       case R_SH_DIR32:
!       case R_SH_REL32:
! 	r_symndx = ELF32_R_SYM (rel->r_info);
! 	if (r_symndx >= symtab_hdr->sh_info)
! 	  {
! 	    struct elf_sh_link_hash_entry *eh;
! 	    struct elf_sh_dyn_relocs **pp;
! 	    struct elf_sh_dyn_relocs *p;
  
! 	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
  
! 	    if (!info->shared && h->plt.refcount > 0)
! 	      h->plt.refcount -= 1;
  
! 	    eh = (struct elf_sh_link_hash_entry *) h;
  
! 	    for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
! 	      if (p->sec == sec)
! 		{
! 		  if (ELF32_R_TYPE (rel->r_info) == R_SH_REL32)
! 		    p->pc_count -= 1;
! 		  p->count -= 1;
! 		  if (p->count == 0)
! 		    *pp = p->next;
! 		  break;
! 		}
! 	  }
! 	break;
  
!       case R_SH_PLT32:
  #ifdef INCLUDE_SHMEDIA
!       case R_SH_PLT_LOW16:
!       case R_SH_PLT_MEDLOW16:
!       case R_SH_PLT_MEDHI16:
!       case R_SH_PLT_HI16:
  #endif
! 	r_symndx = ELF32_R_SYM (rel->r_info);
! 	if (r_symndx >= symtab_hdr->sh_info)
! 	  {
! 	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	    if (h->plt.refcount > 0)
! 	      h->plt.refcount -= 1;
! 	  }
! 	break;
  
!       case R_SH_GOTPLT32:
  #ifdef INCLUDE_SHMEDIA
!       case R_SH_GOTPLT_LOW16:
!       case R_SH_GOTPLT_MEDLOW16:
!       case R_SH_GOTPLT_MEDHI16:
!       case R_SH_GOTPLT_HI16:
!       case R_SH_GOTPLT10BY4:
!       case R_SH_GOTPLT10BY8:
  #endif
! 	r_symndx = ELF32_R_SYM (rel->r_info);
! 	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)
! 	  {
! 	    if (local_got_refcounts[r_symndx] > 0)
! 	      local_got_refcounts[r_symndx] -= 1;
! 	  }
! 	break;
  
!       default:
! 	break;
!       }
  
    return true;
  }
--- 5242,5401 ----
  
    relend = relocs + sec->reloc_count;
    for (rel = relocs; rel < relend; rel++)
!     {
! #ifdef INCLUDE_SHMEDIA
!       int seen_stt_datalabel = 0;
  #endif
  
!       r_symndx = ELF32_R_SYM (rel->r_info);
!       if (r_symndx < symtab_hdr->sh_info)
! 	h = NULL;
!       else
! 	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! #ifdef INCLUDE_SHMEDIA
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    {
! 	      seen_stt_datalabel |= h->type == STT_DATALABEL;
! 	      h = (struct elf_link_hash_entry *) h->root.u.i.link;
! 	    }
! #endif
! 	}
!       eh = (struct elf_sh_link_hash_entry *) h;
  
!       switch (ELF32_R_TYPE (rel->r_info))
! 	{
! 	case R_SH_GOT32:
! 	case R_SH_GOTOFF:
! 	case R_SH_GOTPC:
! #ifdef INCLUDE_SHMEDIA
! 	case R_SH_GOT_LOW16:
! 	case R_SH_GOT_MEDLOW16:
! 	case R_SH_GOT_MEDHI16:
! 	case R_SH_GOT_HI16:
! 	case R_SH_GOT10BY4:
! 	case R_SH_GOT10BY8:
! 	case R_SH_GOTOFF_LOW16:
! 	case R_SH_GOTOFF_MEDLOW16:
! 	case R_SH_GOTOFF_MEDHI16:
! 	case R_SH_GOTOFF_HI16:
! 	case R_SH_GOTPC_LOW16:
! 	case R_SH_GOTPC_MEDLOW16:
! 	case R_SH_GOTPC_MEDHI16:
! 	case R_SH_GOTPC_HI16:
! #endif
! 	  if (h != NULL)
! 	    {
! #ifdef INCLUDE_SHMEDIA
! 	      if (seen_stt_datalabel)
! 		{
! 		  if (eh->datalabel_got.refcount > 0)
! 		    eh->datalabel_got.refcount -= 1;
! 		}
! 	      else
! #endif
! 		if (h->got.refcount > 0)
! 		  h->got.refcount -= 1;
! 	    }
! 	  else if (local_got_refcounts != NULL)
! 	    {
! #ifdef INCLUDE_SHMEDIA
! 	      if (rel->r_addend & 1)
! 		{
! 		  if (local_got_refcounts[symtab_hdr->sh_info + r_symndx] > 0)
! 		    local_got_refcounts[symtab_hdr->sh_info + r_symndx] -= 1;
! 		}
! 	      else
! #endif
! 		if (local_got_refcounts[r_symndx] > 0)
! 		  local_got_refcounts[r_symndx] -= 1;
! 	    }
! 	  break;
  
! 	case R_SH_DIR32:
! 	case R_SH_REL32:
! 	  if (h != NULL)
! 	    {
! 	      struct elf_sh_dyn_relocs **pp;
! 	      struct elf_sh_dyn_relocs *p;
  
! 	      if (!info->shared && h->plt.refcount > 0)
! 		h->plt.refcount -= 1;
  
! 	      for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
! 		if (p->sec == sec)
! 		  {
! 		    if (ELF32_R_TYPE (rel->r_info) == R_SH_REL32)
! 		      p->pc_count -= 1;
! 		    p->count -= 1;
! 		    if (p->count == 0)
! 		      *pp = p->next;
! 		    break;
! 		  }
! 	    }
! 	  break;
  
! 	case R_SH_PLT32:
  #ifdef INCLUDE_SHMEDIA
! 	case R_SH_PLT_LOW16:
! 	case R_SH_PLT_MEDLOW16:
! 	case R_SH_PLT_MEDHI16:
! 	case R_SH_PLT_HI16:
  #endif
! 	  if (h != NULL)
! 	    {
! 	      if (h->plt.refcount > 0)
! 		h->plt.refcount -= 1;
! 	    }
! 	  break;
  
! 	case R_SH_GOTPLT32:
! #ifdef INCLUDE_SHMEDIA
! 	case R_SH_GOTPLT_LOW16:
! 	case R_SH_GOTPLT_MEDLOW16:
! 	case R_SH_GOTPLT_MEDHI16:
! 	case R_SH_GOTPLT_HI16:
! 	case R_SH_GOTPLT10BY4:
! 	case R_SH_GOTPLT10BY8:
! #endif
! 	  if (h != NULL)
! 	    {
! 	      if (eh->gotplt_refcount > 0)
! 		{
! 		  eh->gotplt_refcount -= 1;
! 		  if (h->plt.refcount > 0)
! 		    h->plt.refcount -= 1;
! 		}
  #ifdef INCLUDE_SHMEDIA
! 	      else if (seen_stt_datalabel)
! 		{
! 		  if (eh->datalabel_got.refcount > 0)
! 		    eh->datalabel_got.refcount -= 1;
! 		}
  #endif
! 	      else if (h->got.refcount > 0)
! 		h->got.refcount -= 1;
! 	    }
! 	  else if (local_got_refcounts != NULL)
! 	    {
! #ifdef INCLUDE_SHMEDIA
! 	      if (rel->r_addend & 1)
! 		{
! 		  if (local_got_refcounts[symtab_hdr->sh_info + r_symndx] > 0)
! 		    local_got_refcounts[symtab_hdr->sh_info + r_symndx] -= 1;
! 		}
! 	      else
! #endif
! 		if (local_got_refcounts[r_symndx] > 0)
! 		  local_got_refcounts[r_symndx] -= 1;
! 	    }
! 	  break;
  
! 	default:
! 	  break;
! 	}
!     }
  
    return true;
  }
*************** sh_elf_copy_indirect_symbol (bed, dir, i
*** 5349,5354 ****
--- 5408,5416 ----
       struct elf_link_hash_entry *dir, *ind;
  {
    struct elf_sh_link_hash_entry *edir, *eind;
+ #ifdef INCLUDE_SHMEDIA
+   bfd_signed_vma tmp;
+ #endif
  
    edir = (struct elf_sh_link_hash_entry *) dir;
    eind = (struct elf_sh_link_hash_entry *) ind;
*************** sh_elf_copy_indirect_symbol (bed, dir, i
*** 5387,5392 ****
--- 5449,5464 ----
      }
    edir->gotplt_refcount = eind->gotplt_refcount;
    eind->gotplt_refcount = 0;
+ #ifdef INCLUDE_SHMEDIA
+   tmp = edir->datalabel_got.refcount;
+   if (tmp < 1)
+     {
+       edir->datalabel_got.refcount = eind->datalabel_got.refcount;
+       eind->datalabel_got.refcount = tmp;
+     }
+   else
+     BFD_ASSERT (eind->datalabel_got.refcount < 1);
+ #endif
  
    _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
  }
*************** sh_elf_check_relocs (abfd, info, sec, re
*** 5435,5446 ****
      {
        struct elf_link_hash_entry *h;
        unsigned long r_symndx;
  
        r_symndx = ELF32_R_SYM (rel->r_info);
        if (r_symndx < symtab_hdr->sh_info)
  	h = NULL;
        else
! 	h = sym_hashes[r_symndx - symtab_hdr->sh_info];
  
        /* Some relocs require a global offset table.  */
        if (htab->sgot == NULL)
--- 5507,5531 ----
      {
        struct elf_link_hash_entry *h;
        unsigned long r_symndx;
+ #ifdef INCLUDE_SHMEDIA
+       int seen_stt_datalabel = 0;
+ #endif
  
        r_symndx = ELF32_R_SYM (rel->r_info);
        if (r_symndx < symtab_hdr->sh_info)
  	h = NULL;
        else
! 	{
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! #ifdef INCLUDE_SHMEDIA
! 	  while (h->root.type == bfd_link_hash_indirect
! 		 || h->root.type == bfd_link_hash_warning)
! 	    {
! 	      seen_stt_datalabel |= h->type == STT_DATALABEL;
! 	      h = (struct elf_link_hash_entry *) h->root.u.i.link;
! 	    }
! #endif
! 	}
  
        /* Some relocs require a global offset table.  */
        if (htab->sgot == NULL)
*************** sh_elf_check_relocs (abfd, info, sec, re
*** 5511,5517 ****
  	case R_SH_GOT10BY8:
  #endif
  	  if (h != NULL)
! 	    h->got.refcount += 1;
  	  else
  	    {
  	      bfd_signed_vma *local_got_refcounts;
--- 5596,5610 ----
  	case R_SH_GOT10BY8:
  #endif
  	  if (h != NULL)
! 	    {
! #ifdef INCLUDE_SHMEDIA
! 	      if (seen_stt_datalabel)
! 		((struct elf_sh_link_hash_entry *) h)->datalabel_got.refcount
! 		  += 1;
! 	      else
! #endif
! 		h->got.refcount += 1;
! 	    }
  	  else
  	    {
  	      bfd_signed_vma *local_got_refcounts;
*************** sh_elf_check_relocs (abfd, info, sec, re
*** 5536,5542 ****
  		    return false;
  		  elf_local_got_refcounts (abfd) = local_got_refcounts;
  		}
! 	      local_got_refcounts[r_symndx] += 1;
  	    }
  	  break;
  
--- 5629,5640 ----
  		    return false;
  		  elf_local_got_refcounts (abfd) = local_got_refcounts;
  		}
! #ifdef INCLUDE_SHMEDIA
! 	      if (rel->r_addend & 1)
! 		local_got_refcounts[symtab_hdr->sh_info + r_symndx] += 1;
! 	      else
! #endif
! 		local_got_refcounts[r_symndx] += 1;
  	    }
  	  break;
  
*************** sh_elf_finish_dynamic_symbol (output_bfd
*** 6036,6041 ****
--- 6134,6193 ----
  				  + srel->reloc_count));
        ++srel->reloc_count;
      }
+ 
+ #ifdef INCLUDE_SHMEDIA
+   {
+     struct elf_sh_link_hash_entry *eh;
+ 
+     eh = (struct elf_sh_link_hash_entry *) h;
+     if (eh->datalabel_got.offset != (bfd_vma) -1)
+       {
+ 	asection *sgot;
+ 	asection *srel;
+ 	Elf_Internal_Rela rel;
+ 
+ 	/* This symbol has a datalabel entry in the global offset table.
+ 	   Set it up.  */
+ 
+ 	sgot = htab->sgot;
+ 	srel = htab->srelgot;
+ 	BFD_ASSERT (sgot != NULL && srel != NULL);
+ 
+ 	rel.r_offset = (sgot->output_section->vma
+ 			+ sgot->output_offset
+ 			+ (eh->datalabel_got.offset &~ (bfd_vma) 1));
+ 
+ 	/* If this is a static link, or it is a -Bsymbolic link and the
+ 	   symbol is defined locally or was forced to be local because
+ 	   of a version file, we just want to emit a RELATIVE reloc.
+ 	   The entry in the global offset table will already have been
+ 	   initialized in the relocate_section function.  */
+ 	if (info->shared
+ 	    && (info->symbolic
+ 		|| h->dynindx == -1
+ 		|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
+ 	    && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ 	  {
+ 	    rel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
+ 	    rel.r_addend = (h->root.u.def.value
+ 			    + h->root.u.def.section->output_section->vma
+ 			    + h->root.u.def.section->output_offset);
+ 	  }
+ 	else
+ 	  {
+ 	    bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents
+ 			+ eh->datalabel_got.offset);
+ 	    rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_GLOB_DAT);
+ 	    rel.r_addend = 0;
+ 	  }
+ 
+ 	bfd_elf32_swap_reloca_out (output_bfd, &rel,
+ 				   ((Elf32_External_Rela *) srel->contents
+ 				    + srel->reloc_count));
+ 	++srel->reloc_count;
+       }
+   }
+ #endif
  
    if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
      {

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2002-10-14  5:11 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-10-11 13:04 [Patch] sh64: Fix refcounting for SHmedia Clarke, Stephen
2002-10-13 22:11 ` Hans-Peter Nilsson
  -- strict thread matches above, loose matches on Subject: below --
2002-10-10 16:59 Clarke, Stephen
2002-10-11  2:33 ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).