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]

backend gc_sweep_hook simplification


Simplifies gc_sweep_hook for those that need to remove dynamic relocs.
Fixes some SPARC bugs in this area too.

	* elf32-hppa.c (elf32_hppa_gc_sweep_hook): Simplify dynamic reloc
	removal.  Localize vars.  Remove unnecessary dynobj test.
	* elf32-i386 (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Pass SHARED instead
	of INFO.
	(allocate_dynrelocs): Adjust WILL_CALL_FINISH_DYNAMIC_SYMBOL uses,
	and optimize.
	(elf_i386_relocate_section): Likewise.
	(elf_i386_gc_sweep_hook): Simplify dyn reloc removal.  Localize vars.
	* elf32-s390.c (elf_s390_gc_sweep_hook): Likewise.
	* elf32-sh.c (sh_elf_gc_sweep_hook): Likewise.
	* elf64-s390.c (elf_s390_gc_sweep_hook): Likewise.
	* elf64-x86-64.c (elf64_x86_64_gc_sweep_hook): Likewise.
	* elf32-sparc.c (elf32_sparc_gc_sweep_hook): Likewise.  Remove
	local_dynrel for section too.  Don't touch HIPLT22, LOPLT10, PCPLT32
	or PCPLT10 relocs.  Don't subtract twice on PLT32 relocs.
	Formatting.

Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.96
diff -u -w -p -r1.96 elf32-hppa.c
--- bfd/elf32-hppa.c	17 Feb 2003 18:24:38 -0000	1.96
+++ bfd/elf32-hppa.c	19 Feb 2003 13:41:48 -0000
@@ -1685,10 +1685,6 @@ elf32_hppa_gc_sweep_hook (abfd, info, se
   bfd_signed_vma *local_got_refcounts;
   bfd_signed_vma *local_plt_refcounts;
   const Elf_Internal_Rela *rel, *relend;
-  unsigned long r_symndx;
-  struct elf_link_hash_entry *h;
-  struct elf32_hppa_link_hash_table *htab;
-  bfd *dynobj;
 
   elf_section_data (sec)->local_dynrel = NULL;
 
@@ -1698,22 +1694,41 @@ elf32_hppa_gc_sweep_hook (abfd, info, se
   local_plt_refcounts = local_got_refcounts;
   if (local_plt_refcounts != NULL)
     local_plt_refcounts += symtab_hdr->sh_info;
-  htab = hppa_link_hash_table (info);
-  dynobj = htab->elf.dynobj;
-  if (dynobj == NULL)
-    return TRUE;
 
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
-    switch ((unsigned int) ELF32_R_TYPE (rel->r_info))
       {
-      case R_PARISC_DLTIND14F:
-      case R_PARISC_DLTIND14R:
-      case R_PARISC_DLTIND21L:
+      unsigned long r_symndx;
+      unsigned int r_type;
+      struct elf_link_hash_entry *h = NULL;
+
 	r_symndx = ELF32_R_SYM (rel->r_info);
 	if (r_symndx >= symtab_hdr->sh_info)
 	  {
+	  struct elf32_hppa_link_hash_entry *eh;
+	  struct elf32_hppa_dyn_reloc_entry **pp;
+	  struct elf32_hppa_dyn_reloc_entry *p;
+
 	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+	  eh = (struct elf32_hppa_link_hash_entry *) h;
+
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+	    if (p->sec == sec)
+	      {
+		/* Everything must go for SEC.  */
+		*pp = p->next;
+		break;
+	      }
+	}
+
+      r_type = ELF32_R_TYPE (rel->r_info);
+      switch (r_type)
+	{
+	case R_PARISC_DLTIND14F:
+	case R_PARISC_DLTIND14R:
+	case R_PARISC_DLTIND21L:
+	  if (h != NULL)
+	    {
 	    if (h->got.refcount > 0)
 	      h->got.refcount -= 1;
 	  }
@@ -1728,10 +1743,8 @@ elf32_hppa_gc_sweep_hook (abfd, info, se
       case R_PARISC_PCREL17C:
       case R_PARISC_PCREL17F:
       case R_PARISC_PCREL22F:
-	r_symndx = ELF32_R_SYM (rel->r_info);
-	if (r_symndx >= symtab_hdr->sh_info)
+	  if (h != NULL)
 	  {
-	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 	    if (h->plt.refcount > 0)
 	      h->plt.refcount -= 1;
 	  }
@@ -1740,32 +1753,10 @@ elf32_hppa_gc_sweep_hook (abfd, info, se
       case R_PARISC_PLABEL14R:
       case R_PARISC_PLABEL21L:
       case R_PARISC_PLABEL32:
-	r_symndx = ELF32_R_SYM (rel->r_info);
-	if (r_symndx >= symtab_hdr->sh_info)
+	  if (h != NULL)
 	  {
-	    struct elf32_hppa_link_hash_entry *eh;
-	    struct elf32_hppa_dyn_reloc_entry **pp;
-	    struct elf32_hppa_dyn_reloc_entry *p;
-
-	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-
 	    if (h->plt.refcount > 0)
 	      h->plt.refcount -= 1;
-
-	    eh = (struct elf32_hppa_link_hash_entry *) h;
-
-	    for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
-	      if (p->sec == sec)
-		{
-#if RELATIVE_DYNRELOCS
-		  if (!IS_ABSOLUTE_RELOC (rtype))
-		    p->relative_count -= 1;
-#endif
-		  p->count -= 1;
-		  if (p->count == 0)
-		    *pp = p->next;
-		  break;
-		}
 	  }
 	else if (local_plt_refcounts != NULL)
 	  {
@@ -1774,36 +1765,10 @@ elf32_hppa_gc_sweep_hook (abfd, info, se
 	  }
 	break;
 
-      case R_PARISC_DIR32:
-	r_symndx = ELF32_R_SYM (rel->r_info);
-	if (r_symndx >= symtab_hdr->sh_info)
-	  {
-	    struct elf32_hppa_link_hash_entry *eh;
-	    struct elf32_hppa_dyn_reloc_entry **pp;
-	    struct elf32_hppa_dyn_reloc_entry *p;
-
-	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-
-	    eh = (struct elf32_hppa_link_hash_entry *) h;
-
-	    for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
-	      if (p->sec == sec)
-		{
-#if RELATIVE_DYNRELOCS
-		  if (!IS_ABSOLUTE_RELOC (R_PARISC_DIR32))
-		    p->relative_count -= 1;
-#endif
-		  p->count -= 1;
-		  if (p->count == 0)
-		    *pp = p->next;
-		  break;
-		}
-	  }
-	break;
-
       default:
 	break;
       }
+    }
 
   return TRUE;
 }
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.94
diff -u -w -p -r1.94 elf32-i386.c
--- bfd/elf32-i386.c	17 Feb 2003 18:24:39 -0000	1.94
+++ bfd/elf32-i386.c	19 Feb 2003 13:41:50 -0000
@@ -1279,9 +1279,6 @@ elf_i386_gc_sweep_hook (abfd, info, sec,
   struct elf_link_hash_entry **sym_hashes;
   bfd_signed_vma *local_got_refcounts;
   const Elf_Internal_Rela *rel, *relend;
-  unsigned long r_symndx;
-  int r_type;
-  struct elf_link_hash_entry *h;
 
   elf_section_data (sec)->local_dynrel = NULL;
 
@@ -1291,10 +1288,33 @@ elf_i386_gc_sweep_hook (abfd, info, sec,
 
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
-    switch ((r_type = elf_i386_tls_transition (info,
-					       ELF32_R_TYPE (rel->r_info),
-					       ELF32_R_SYM (rel->r_info)
-					       >= symtab_hdr->sh_info)))
+    {
+      unsigned long r_symndx;
+      unsigned int r_type;
+      struct elf_link_hash_entry *h = NULL;
+
+      r_symndx = ELF32_R_SYM (rel->r_info);
+      if (r_symndx >= symtab_hdr->sh_info)
+	{
+	  struct elf_i386_link_hash_entry *eh;
+	  struct elf_i386_dyn_relocs **pp;
+	  struct elf_i386_dyn_relocs *p;
+
+	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+	  eh = (struct elf_i386_link_hash_entry *) h;
+
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+	    if (p->sec == sec)
+	      {
+		/* Everything must go for SEC.  */
+		*pp = p->next;
+		break;
+	      }
+	}
+
+      r_type = ELF32_R_TYPE (rel->r_info);
+      r_type = elf_i386_tls_transition (info, r_type, h != NULL);
+      switch (r_type)
       {
       case R_386_TLS_LDM:
 	if (elf_i386_hash_table (info)->tls_ldm_got.refcount > 0)
@@ -1306,10 +1326,8 @@ elf_i386_gc_sweep_hook (abfd, info, sec,
       case R_386_TLS_IE:
       case R_386_TLS_GOTIE:
       case R_386_GOT32:
-	r_symndx = ELF32_R_SYM (rel->r_info);
-	if (r_symndx >= symtab_hdr->sh_info)
+	  if (h != NULL)
 	  {
-	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 	    if (h->got.refcount > 0)
 	      h->got.refcount -= 1;
 	  }
@@ -1318,50 +1336,17 @@ elf_i386_gc_sweep_hook (abfd, info, sec,
 	    if (local_got_refcounts[r_symndx] > 0)
 	      local_got_refcounts[r_symndx] -= 1;
 	  }
-	if (r_type != R_386_TLS_IE)
-	  break;
-	/* Fall through */
-
-      case R_386_TLS_LE_32:
-      case R_386_TLS_LE:
-        if (!info->shared)
 	  break;
-	/* Fall through */
 
       case R_386_32:
       case R_386_PC32:
-	r_symndx = ELF32_R_SYM (rel->r_info);
-	if (r_symndx >= symtab_hdr->sh_info)
-	  {
-	    struct elf_i386_link_hash_entry *eh;
-	    struct elf_i386_dyn_relocs **pp;
-	    struct elf_i386_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_i386_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_386_PC32)
-		    p->pc_count -= 1;
-		  p->count -= 1;
-		  if (p->count == 0)
-		    *pp = p->next;
-		  break;
-		}
-	  }
+	  if (info->shared)
 	break;
+	  /* Fall through */
 
       case R_386_PLT32:
-	r_symndx = ELF32_R_SYM (rel->r_info);
-	if (r_symndx >= symtab_hdr->sh_info)
+	  if (h != NULL)
 	  {
-	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 	    if (h->plt.refcount > 0)
 	      h->plt.refcount -= 1;
 	  }
@@ -1370,6 +1355,7 @@ elf_i386_gc_sweep_hook (abfd, info, sec,
       default:
 	break;
       }
+    }
 
   return TRUE;
 }
@@ -1523,9 +1510,9 @@ elf_i386_adjust_dynamic_symbol (info, h)
    will be called from elflink.h.  If elflink.h doesn't call our
    finish_dynamic_symbol routine, we'll need to do something about
    initializing any .plt and .got entries in elf_i386_relocate_section.  */
-#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \
+#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \
   ((DYN)								\
-   && ((INFO)->shared							\
+   && ((SHARED)								\
        || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)	\
    && ((H)->dynindx != -1						\
        || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0))
@@ -1567,7 +1554,8 @@ allocate_dynrelocs (h, inf)
 	    return FALSE;
 	}
 
-      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
+      if (info->shared
+	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
 	{
 	  asection *s = htab->splt;
 
@@ -1653,7 +1641,8 @@ allocate_dynrelocs (h, inf)
 	htab->srelgot->_raw_size += sizeof (Elf32_External_Rel);
       else if (tls_type == GOT_TLS_GD)
 	htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rel);
-      else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
+      else if (info->shared
+	       || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
 	htab->srelgot->_raw_size += sizeof (Elf32_External_Rel);
     }
   else
@@ -2289,7 +2281,7 @@ elf_i386_relocate_section (output_bfd, i
 
 	      off = h->got.offset;
 	      dyn = htab->elf.dynamic_sections_created;
-	      if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)
+	      if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
 		  || (info->shared
 		      && (info->symbolic
 			  || h->dynindx == -1
Index: bfd/elf32-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-s390.c,v
retrieving revision 1.36
diff -u -w -p -r1.36 elf32-s390.c
--- bfd/elf32-s390.c	17 Feb 2003 18:24:39 -0000	1.36
+++ bfd/elf32-s390.c	19 Feb 2003 13:41:51 -0000
@@ -1327,9 +1327,6 @@ elf_s390_gc_sweep_hook (abfd, info, sec,
   struct elf_link_hash_entry **sym_hashes;
   bfd_signed_vma *local_got_refcounts;
   const Elf_Internal_Rela *rel, *relend;
-  unsigned long r_symndx;
-  int r_type;
-  struct elf_link_hash_entry *h;
 
   elf_section_data (sec)->local_dynrel = NULL;
 
@@ -1340,16 +1337,31 @@ elf_s390_gc_sweep_hook (abfd, info, sec,
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
     {
+      unsigned long r_symndx;
+      unsigned int r_type;
+      struct elf_link_hash_entry *h = NULL;
+
       r_symndx = ELF32_R_SYM (rel->r_info);
+      if (r_symndx >= symtab_hdr->sh_info)
+	{
+	  struct elf_s390_link_hash_entry *eh;
+	  struct elf_s390_dyn_relocs **pp;
+	  struct elf_s390_dyn_relocs *p;
 
-      if (r_symndx < symtab_hdr->sh_info)
-	h = NULL;
-      else
 	h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+	  eh = (struct elf_s390_link_hash_entry *) h;
 
-      r_type = elf_s390_tls_transition (info,
-					ELF32_R_TYPE (rel->r_info),
-					r_symndx >= symtab_hdr->sh_info);
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+	    if (p->sec == sec)
+	      {
+		/* Everything must go for SEC.  */
+		*pp = p->next;
+		break;
+	      }
+	}
+
+      r_type = ELF32_R_TYPE (rel->r_info);
+      r_type = elf_s390_tls_transition (info, r_type, h != NULL);
       switch (r_type)
 	{
 	case R_390_TLS_LDM32:
@@ -1380,14 +1392,7 @@ elf_s390_gc_sweep_hook (abfd, info, sec,
 	      if (local_got_refcounts[r_symndx] > 0)
 		local_got_refcounts[r_symndx] -= 1;
 	    }
-	  if (r_type != R_390_TLS_IE32)
-	    break;
-	  /* Fall through.  */
-	  
-	case R_390_TLS_LE32:
-	  if (!info->shared)
 	    break;
-	  /* Fall through.  */
 
 	case R_390_8:
 	case R_390_12:
@@ -1397,32 +1402,9 @@ elf_s390_gc_sweep_hook (abfd, info, sec,
 	case R_390_PC16DBL:
 	case R_390_PC32DBL:
 	case R_390_PC32:
-	  if (h != NULL)
-	    {
-	      struct elf_s390_link_hash_entry *eh;
-	      struct elf_s390_dyn_relocs **pp;
-	      struct elf_s390_dyn_relocs *p;
-	      
-	      if (!info->shared && h->plt.refcount > 0)
-		h->plt.refcount -= 1;
-	      
-	      eh = (struct elf_s390_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_390_PC16
-			|| ELF32_R_TYPE (rel->r_info) == R_390_PC16DBL
-			|| ELF32_R_TYPE (rel->r_info) == R_390_PC32DBL
-			|| ELF32_R_TYPE (rel->r_info) == R_390_PC32)
-		      p->pc_count -= 1;
-		    p->count -= 1;
-		    if (p->count == 0)
-		      *pp = p->next;
-		    break;
-		  }
-	    }
+	  if (info->shared)
 	  break;
+	  /* Fall through.  */
 	  
 	case R_390_PLT16DBL:
 	case R_390_PLT32DBL:
@@ -3001,8 +2983,8 @@ elf_s390_finish_dynamic_symbol (output_b
       /* If offset is > 32768, branch to a previous branch
          390 can only handle +-64 K jumps.  */
       if ( -32768 > (int) relative_offset )
-          relative_offset =
-	    -(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2);
+	relative_offset
+	  = -(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2);
 
       /* Fill in the entry in the procedure linkage table.  */
       if (!info->shared)
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.72
diff -u -w -p -r1.72 elf32-sh.c
--- bfd/elf32-sh.c	17 Feb 2003 18:24:39 -0000	1.72
+++ bfd/elf32-sh.c	19 Feb 2003 13:41:56 -0000
@@ -5919,9 +5919,6 @@ sh_elf_gc_sweep_hook (abfd, info, sec, r
   struct elf_link_hash_entry **sym_hashes;
   bfd_signed_vma *local_got_refcounts;
   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;
 
@@ -5932,15 +5929,20 @@ sh_elf_gc_sweep_hook (abfd, info, sec, r
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
     {
+      unsigned long r_symndx;
+      unsigned int r_type;
+      struct elf_link_hash_entry *h = NULL;
 #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
+      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];
 #ifdef INCLUDE_SHMEDIA
 	  while (h->root.type == bfd_link_hash_indirect
@@ -5950,12 +5952,18 @@ sh_elf_gc_sweep_hook (abfd, info, sec, r
 	      h = (struct elf_link_hash_entry *) h->root.u.i.link;
 	    }
 #endif
-	}
       eh = (struct elf_sh_link_hash_entry *) h;
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+	    if (p->sec == sec)
+	      {
+		/* Everything must go for SEC.  */
+		*pp = p->next;
+		break;
+	      }
+	}
 
-      switch (sh_elf_optimized_tls_reloc (info, ELF32_R_TYPE (rel->r_info),
-					  ELF32_R_SYM (rel->r_info)
-					  >= symtab_hdr->sh_info))
+      r_type = ELF32_R_TYPE (rel->r_info);
+      switch (sh_elf_optimized_tls_reloc (info, r_type, h != NULL))
 	{
 	case R_SH_TLS_LD_32:
 	  if (sh_elf_hash_table (info)->tls_ldm_got.refcount > 0)
@@ -5988,6 +5996,8 @@ sh_elf_gc_sweep_hook (abfd, info, sec, r
 #ifdef INCLUDE_SHMEDIA
 	      if (seen_stt_datalabel)
 		{
+		  struct elf_sh_link_hash_entry *eh;
+		  eh = (struct elf_sh_link_hash_entry *) h;
 		  if (eh->datalabel_got.refcount > 0)
 		    eh->datalabel_got.refcount -= 1;
 		}
@@ -6013,27 +6023,9 @@ sh_elf_gc_sweep_hook (abfd, info, sec, r
 
 	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;
-		  }
-	    }
+	  if (info->shared)
 	  break;
+	  /* Fall thru */
 
 	case R_SH_PLT32:
 #ifdef INCLUDE_SHMEDIA
@@ -6060,6 +6052,8 @@ sh_elf_gc_sweep_hook (abfd, info, sec, r
 #endif
 	  if (h != NULL)
 	    {
+	      struct elf_sh_link_hash_entry *eh;
+	      eh = (struct elf_sh_link_hash_entry *) h;
 	      if (eh->gotplt_refcount > 0)
 		{
 		  eh->gotplt_refcount -= 1;
Index: bfd/elf32-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sparc.c,v
retrieving revision 1.48
diff -c -p -r1.48 elf32-sparc.c
*** bfd/elf32-sparc.c	17 Feb 2003 18:24:39 -0000	1.48
--- bfd/elf32-sparc.c	19 Feb 2003 13:50:04 -0000
*************** static struct bfd_hash_entry *link_hash_
*** 63,70 ****
    PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
  static struct bfd_link_hash_table *elf32_sparc_link_hash_table_create
    PARAMS ((bfd *));
! static bfd_boolean create_got_section PARAMS ((bfd *,
! 					       struct bfd_link_info *));
  static bfd_boolean elf32_sparc_create_dynamic_sections
    PARAMS ((bfd *, struct bfd_link_info *));
  static void elf32_sparc_copy_indirect_symbol
--- 63,70 ----
    PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
  static struct bfd_link_hash_table *elf32_sparc_link_hash_table_create
    PARAMS ((bfd *));
! static bfd_boolean create_got_section
!   PARAMS ((bfd *, struct bfd_link_info *));
  static bfd_boolean elf32_sparc_create_dynamic_sections
    PARAMS ((bfd *, struct bfd_link_info *));
  static void elf32_sparc_copy_indirect_symbol
*************** elf32_sparc_reloc_type_lookup (abfd, cod
*** 291,301 ****
        return &elf32_sparc_rev32_howto;
  
      default:
!       for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map); i++)
!         {
!           if (sparc_reloc_map[i].bfd_reloc_val == code)
! 	    return &_bfd_sparc_elf_howto_table[(int) sparc_reloc_map[i].elf_reloc_val];
!         }
      }
      bfd_set_error (bfd_error_bad_value);
      return NULL;
--- 291,304 ----
        return &elf32_sparc_rev32_howto;
  
      default:
!       for (i = 0;
! 	   i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map);
! 	   i++)
! 	{
! 	  if (sparc_reloc_map[i].bfd_reloc_val == code)
! 	    return (_bfd_sparc_elf_howto_table
! 		    + (int) sparc_reloc_map[i].elf_reloc_val);
! 	}
      }
      bfd_set_error (bfd_error_bad_value);
      return NULL;
*************** elf32_sparc_gc_sweep_hook (abfd, info, s
*** 1294,1307 ****
       asection *sec;
       const Elf_Internal_Rela *relocs;
  {
- 
    Elf_Internal_Shdr *symtab_hdr;
    struct elf_link_hash_entry **sym_hashes;
    bfd_signed_vma *local_got_refcounts;
    const Elf_Internal_Rela *rel, *relend;
!   unsigned long r_symndx;
!   int r_type;
!   struct elf_link_hash_entry *h;
  
    symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    sym_hashes = elf_sym_hashes (abfd);
--- 1297,1308 ----
       asection *sec;
       const Elf_Internal_Rela *relocs;
  {
    Elf_Internal_Shdr *symtab_hdr;
    struct elf_link_hash_entry **sym_hashes;
    bfd_signed_vma *local_got_refcounts;
    const Elf_Internal_Rela *rel, *relend;
! 
!   elf_section_data (sec)->local_dynrel = NULL;
  
    symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    sym_hashes = elf_sym_hashes (abfd);
*************** elf32_sparc_gc_sweep_hook (abfd, info, s
*** 1309,1424 ****
  
    relend = relocs + sec->reloc_count;
    for (rel = relocs; rel < relend; rel++)
!     switch ((r_type = elf32_sparc_tls_transition (info, abfd,
! 						  ELF32_R_TYPE (rel->r_info),
! 						  ELF32_R_SYM (rel->r_info)
! 						  >= symtab_hdr->sh_info)))
!       {
!       case R_SPARC_TLS_LDM_HI22:
!       case R_SPARC_TLS_LDM_LO10:
! 	if (elf32_sparc_hash_table (info)->tls_ldm_got.refcount > 0)
! 	  elf32_sparc_hash_table (info)->tls_ldm_got.refcount -= 1;
! 	break;
! 
!       case R_SPARC_TLS_LE_HIX22:
!       case R_SPARC_TLS_LE_LOX10:
! 	if (info->shared)
! 	  goto r_sparc_plt32;
! 	break;
! 
!       case R_SPARC_PC10:
!       case R_SPARC_PC22:
! 	  if ((r_symndx = ELF32_R_SYM (rel->r_info)) >= symtab_hdr->sh_info
! 	      && strcmp (sym_hashes[r_symndx
! 				    - symtab_hdr->sh_info]->root.root.string,
! 				    "_GLOBAL_OFFSET_TABLE_") == 0)
! 	    break;
! 	  /* Fall through.  */
  
!       case R_SPARC_DISP8:
!       case R_SPARC_DISP16:
!       case R_SPARC_DISP32:
!       case R_SPARC_WDISP30:
!       case R_SPARC_WDISP22:
!       case R_SPARC_WDISP19:
!       case R_SPARC_WDISP16:
!       case R_SPARC_8:
!       case R_SPARC_16:
!       case R_SPARC_32:
!       case R_SPARC_HI22:
!       case R_SPARC_22:
!       case R_SPARC_13:
!       case R_SPARC_LO10:
!       case R_SPARC_UA16:
!       case R_SPARC_UA32:
!       r_sparc_plt32:
! 	r_symndx = ELF32_R_SYM (rel->r_info);
! 	if (r_symndx >= symtab_hdr->sh_info)
! 	  {
! 	    struct elf32_sparc_link_hash_entry *eh;
! 	    struct elf32_sparc_dyn_relocs **pp;
! 	    struct elf32_sparc_dyn_relocs *p;
  
! 	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
  
! 	    if (! info->shared)
! 	      --h->plt.refcount;
  
! 	    eh = (struct elf32_sparc_link_hash_entry *) h;
  
! 	    for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
! 	      if (p->sec == sec)
! 		{
! 		  if (_bfd_sparc_elf_howto_table[r_type].pc_relative)
! 		    p->pc_count -= 1;
! 		  p->count -= 1;
! 		  if (p->count == 0)
! 		    *pp = p->next;
! 		  break;
! 		}
! 	  }
! 	break;
  
!       case R_SPARC_TLS_GD_HI22:
!       case R_SPARC_TLS_GD_LO10:
!       case R_SPARC_TLS_IE_HI22:
!       case R_SPARC_TLS_IE_LO10:
!       case R_SPARC_GOT10:
!       case R_SPARC_GOT13:
!       case R_SPARC_GOT22:
! 	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--;
! 	  }
! 	else
! 	  {
! 	    if (local_got_refcounts[r_symndx] > 0)
! 	      local_got_refcounts[r_symndx]--;
! 	  }
!         break;
  
!       case R_SPARC_PLT32:
!       case R_SPARC_HIPLT22:
!       case R_SPARC_LOPLT10:
!       case R_SPARC_PCPLT32:
!       case R_SPARC_PCPLT10:
! 	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--;
! 	  }
! 	if (r_type == R_SPARC_PLT32)
! 	  goto r_sparc_plt32;
! 	break;
  
!       default:
! 	break;
!       }
  
    return TRUE;
  }
--- 1310,1407 ----
  
    relend = relocs + sec->reloc_count;
    for (rel = relocs; rel < relend; rel++)
!     {
!       unsigned long r_symndx;
!       unsigned int r_type;
!       struct elf_link_hash_entry *h = NULL;
  
!       r_symndx = ELF32_R_SYM (rel->r_info);
!       if (r_symndx >= symtab_hdr->sh_info)
! 	{
! 	  struct elf32_sparc_link_hash_entry *eh;
! 	  struct elf32_sparc_dyn_relocs **pp;
! 	  struct elf32_sparc_dyn_relocs *p;
  
! 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! 	  eh = (struct elf32_sparc_link_hash_entry *) h;
! 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
! 	    if (p->sec == sec)
! 	      {
! 		/* Everything must go for SEC.  */
! 		*pp = p->next;
! 		break;
! 	      }
! 	}
  
!       r_type = ELF32_R_TYPE (rel->r_info);
!       r_type = elf32_sparc_tls_transition (info, abfd, r_type, h != NULL);
!       switch (r_type)
! 	{
! 	case R_SPARC_TLS_LDM_HI22:
! 	case R_SPARC_TLS_LDM_LO10:
! 	  if (elf32_sparc_hash_table (info)->tls_ldm_got.refcount > 0)
! 	    elf32_sparc_hash_table (info)->tls_ldm_got.refcount -= 1;
! 	  break;
  
! 	case R_SPARC_TLS_GD_HI22:
! 	case R_SPARC_TLS_GD_LO10:
! 	case R_SPARC_TLS_IE_HI22:
! 	case R_SPARC_TLS_IE_LO10:
! 	case R_SPARC_GOT10:
! 	case R_SPARC_GOT13:
! 	case R_SPARC_GOT22:
! 	  if (h != NULL)
! 	    {
! 	      if (h->got.refcount > 0)
! 		h->got.refcount--;
! 	    }
! 	  else
! 	    {
! 	      if (local_got_refcounts[r_symndx] > 0)
! 		local_got_refcounts[r_symndx]--;
! 	    }
! 	  break;
  
! 	case R_SPARC_PC10:
! 	case R_SPARC_PC22:
! 	  if (h != NULL
! 	      && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
! 	    break;
! 	  /* Fall through.  */
  
! 	case R_SPARC_DISP8:
! 	case R_SPARC_DISP16:
! 	case R_SPARC_DISP32:
! 	case R_SPARC_WDISP30:
! 	case R_SPARC_WDISP22:
! 	case R_SPARC_WDISP19:
! 	case R_SPARC_WDISP16:
! 	case R_SPARC_8:
! 	case R_SPARC_16:
! 	case R_SPARC_32:
! 	case R_SPARC_HI22:
! 	case R_SPARC_22:
! 	case R_SPARC_13:
! 	case R_SPARC_LO10:
! 	case R_SPARC_UA16:
! 	case R_SPARC_UA32:
! 	case R_SPARC_PLT32:
! 	  if (info->shared)
! 	    break;
! 	  /* Fall through.  */
  
! 	case R_SPARC_WPLT30:
! 	  if (h != NULL)
! 	    {
! 	      if (h->plt.refcount > 0)
! 		h->plt.refcount--;
! 	    }
! 	  break;
  
! 	default:
! 	  break;
! 	}
!     }
  
    return TRUE;
  }
Index: bfd/elf64-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-s390.c,v
retrieving revision 1.36
diff -u -w -p -r1.36 elf64-s390.c
--- bfd/elf64-s390.c	17 Feb 2003 18:24:40 -0000	1.36
+++ bfd/elf64-s390.c	19 Feb 2003 13:41:58 -0000
@@ -1292,9 +1292,6 @@ elf_s390_gc_sweep_hook (abfd, info, sec,
   struct elf_link_hash_entry **sym_hashes;
   bfd_signed_vma *local_got_refcounts;
   const Elf_Internal_Rela *rel, *relend;
-  unsigned long r_symndx;
-  int r_type;
-  struct elf_link_hash_entry *h;
 
   elf_section_data (sec)->local_dynrel = NULL;
 
@@ -1305,16 +1302,31 @@ elf_s390_gc_sweep_hook (abfd, info, sec,
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
     {
+      unsigned long r_symndx;
+      unsigned int r_type;
+      struct elf_link_hash_entry *h = NULL;
+
       r_symndx = ELF64_R_SYM (rel->r_info);
+      if (r_symndx >= symtab_hdr->sh_info)
+	{
+	  struct elf_s390_link_hash_entry *eh;
+	  struct elf_s390_dyn_relocs **pp;
+	  struct elf_s390_dyn_relocs *p;
 
-      if (r_symndx < symtab_hdr->sh_info)
-	h = NULL;
-      else
 	h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+	  eh = (struct elf_s390_link_hash_entry *) h;
 
-      r_type = elf_s390_tls_transition (info,
-					ELF64_R_TYPE (rel->r_info),
-					r_symndx >= symtab_hdr->sh_info);
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+	    if (p->sec == sec)
+	      {
+		/* Everything must go for SEC.  */
+		*pp = p->next;
+		break;
+	      }
+	}
+
+      r_type = ELF64_R_TYPE (rel->r_info);
+      r_type = elf_s390_tls_transition (info, r_type, h != NULL);
       switch (r_type)
 	{
 	case R_390_TLS_LDM64:
@@ -1347,14 +1359,7 @@ elf_s390_gc_sweep_hook (abfd, info, sec,
 	      if (local_got_refcounts[r_symndx] > 0)
 		local_got_refcounts[r_symndx] -= 1;
 	    }
-	  if (r_type != R_390_TLS_IE64)
 	    break;
-	  /* Fall through */
-	  
-	case R_390_TLS_LE64:
-	  if (!info->shared)
-	    break;
-	  /* Fall through */
 
 	case R_390_8:
 	case R_390_12:
@@ -1366,33 +1371,9 @@ elf_s390_gc_sweep_hook (abfd, info, sec,
 	case R_390_PC32:
 	case R_390_PC32DBL:
 	case R_390_PC64:
-	  if (h != NULL)
-	    {
-	      struct elf_s390_link_hash_entry *eh;
-	      struct elf_s390_dyn_relocs **pp;
-	      struct elf_s390_dyn_relocs *p;
-	      
-	      if (!info->shared && h->plt.refcount > 0)
-		h->plt.refcount -= 1;
-	      
-	      eh = (struct elf_s390_link_hash_entry *) h;
-	      
-	      for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
-		if (p->sec == sec)
-		  {
-		    if (ELF64_R_TYPE (rel->r_info) == R_390_PC16
-			|| ELF64_R_TYPE (rel->r_info) == R_390_PC16DBL
-			|| ELF64_R_TYPE (rel->r_info) == R_390_PC32
-			|| ELF64_R_TYPE (rel->r_info) == R_390_PC32DBL
-			|| ELF64_R_TYPE (rel->r_info) == R_390_PC64)
-		      p->pc_count -= 1;
-		    p->count -= 1;
-		    if (p->count == 0)
-		      *pp = p->next;
-		    break;
-		  }
-	    }
+	  if (info->shared)
 	  break;
+	  /* Fall through */
 
 	case R_390_PLT16DBL:
 	case R_390_PLT32:
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.55
diff -u -w -p -r1.55 elf64-x86-64.c
--- bfd/elf64-x86-64.c	17 Feb 2003 18:24:40 -0000	1.55
+++ bfd/elf64-x86-64.c	19 Feb 2003 13:41:58 -0000
@@ -1091,9 +1091,6 @@ elf64_x86_64_gc_sweep_hook (abfd, info, 
   struct elf_link_hash_entry **sym_hashes;
   bfd_signed_vma *local_got_refcounts;
   const Elf_Internal_Rela *rel, *relend;
-  unsigned long r_symndx;
-  int r_type;
-  struct elf_link_hash_entry *h;
 
   elf_section_data (sec)->local_dynrel = NULL;
 
@@ -1103,10 +1100,33 @@ elf64_x86_64_gc_sweep_hook (abfd, info, 
 
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
-    switch ((r_type = elf64_x86_64_tls_transition (info,
-						   ELF64_R_TYPE (rel->r_info),
-						   ELF64_R_SYM (rel->r_info)
-						   >= symtab_hdr->sh_info)))
+    {
+      unsigned long r_symndx;
+      unsigned int r_type;
+      struct elf_link_hash_entry *h = NULL;
+
+      r_symndx = ELF64_R_SYM (rel->r_info);
+      if (r_symndx >= symtab_hdr->sh_info)
+	{
+	  struct elf64_x86_64_link_hash_entry *eh;
+	  struct elf64_x86_64_dyn_relocs **pp;
+	  struct elf64_x86_64_dyn_relocs *p;
+
+	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+	  eh = (struct elf64_x86_64_link_hash_entry *) h;
+
+	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+	    if (p->sec == sec)
+	      {
+		/* Everything must go for SEC.  */
+		*pp = p->next;
+		break;
+	      }
+	}
+
+      r_type = ELF64_R_TYPE (rel->r_info);
+      r_type = elf64_x86_64_tls_transition (info, r_type, h != NULL);
+      switch (r_type)
       {
       case R_X86_64_TLSLD:
 	if (elf64_x86_64_hash_table (info)->tls_ld_got.refcount > 0)
@@ -1117,10 +1137,8 @@ elf64_x86_64_gc_sweep_hook (abfd, info, 
       case R_X86_64_GOTTPOFF:
       case R_X86_64_GOT32:
       case R_X86_64_GOTPCREL:
-	r_symndx = ELF64_R_SYM (rel->r_info);
-	if (r_symndx >= symtab_hdr->sh_info)
+	  if (h != NULL)
 	  {
-	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 	    if (h->got.refcount > 0)
 	      h->got.refcount -= 1;
 	  }
@@ -1139,41 +1157,13 @@ elf64_x86_64_gc_sweep_hook (abfd, info, 
       case R_X86_64_PC8:
       case R_X86_64_PC16:
       case R_X86_64_PC32:
-	r_symndx = ELF64_R_SYM (rel->r_info);
-	if (r_symndx >= symtab_hdr->sh_info)
-	  {
-	    struct elf64_x86_64_link_hash_entry *eh;
-	    struct elf64_x86_64_dyn_relocs **pp;
-	    struct elf64_x86_64_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 elf64_x86_64_link_hash_entry *) h;
-
-	    for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
-	      if (p->sec == sec)
-		{
-		  if (ELF64_R_TYPE (rel->r_info) == R_X86_64_PC8
-		      || ELF64_R_TYPE (rel->r_info) == R_X86_64_PC16
-		      || ELF64_R_TYPE (rel->r_info) == R_X86_64_PC32)
-		    p->pc_count -= 1;
-		  p->count -= 1;
-		  if (p->count == 0)
-		    *pp = p->next;
-		  break;
-		}
-	  }
+	  if (info->shared)
 	break;
-
+	  /* Fall thru */
 
       case R_X86_64_PLT32:
-	r_symndx = ELF64_R_SYM (rel->r_info);
-	if (r_symndx >= symtab_hdr->sh_info)
+	  if (h != NULL)
 	  {
-	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 	    if (h->plt.refcount > 0)
 	      h->plt.refcount -= 1;
 	  }
@@ -1182,6 +1172,7 @@ elf64_x86_64_gc_sweep_hook (abfd, info, 
       default:
 	break;
       }
+    }
 
   return TRUE;
 }

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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