R_PPC64_NONE relocs

Alan Modra amodra@bigpond.net.au
Fri Apr 1 02:50:00 GMT 2005


Kills R_PPC64_NONE dynamic relocs caused by editing the TOC.

	* elf64-ppc.c (ppc64_elf_edit_toc): Account for dynamic relocs
	that we no longer need.

Applying mainline.  I might apply this to the branch a little later,
assuming 2.16 isn't released in the next week or so.

Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.194
diff -u -p -r1.194 elf64-ppc.c
--- bfd/elf64-ppc.c	5 Mar 2005 11:44:14 -0000	1.194
+++ bfd/elf64-ppc.c	1 Apr 2005 02:00:21 -0000
@@ -7055,6 +7056,107 @@ ppc64_elf_edit_toc (bfd *obfd ATTRIBUTE_
 		    wrel->r_addend = rel->r_addend;
 		    ++wrel;
 		  }
+		else
+		  {
+		    unsigned long r_symndx;
+		    enum elf_ppc64_reloc_type r_type;
+		    asection *sym_sec;
+		    struct elf_link_hash_entry *h;
+		    Elf_Internal_Sym *sym;
+		    struct ppc_dyn_relocs *p;
+		    struct ppc_dyn_relocs **head;
+
+		    /* Can this reloc be dynamic?
+		       This switch, and later tests here should be kept
+		       in sync with the code in check_relocs.  */
+		    r_type = ELF64_R_TYPE (rel->r_info);
+		    switch (r_type)
+		      {
+		      default:
+			continue;
+
+		      case R_PPC64_TPREL16:
+		      case R_PPC64_TPREL16_LO:
+		      case R_PPC64_TPREL16_HI:
+		      case R_PPC64_TPREL16_HA:
+		      case R_PPC64_TPREL16_DS:
+		      case R_PPC64_TPREL16_LO_DS:
+		      case R_PPC64_TPREL16_HIGHER:
+		      case R_PPC64_TPREL16_HIGHERA:
+		      case R_PPC64_TPREL16_HIGHEST:
+		      case R_PPC64_TPREL16_HIGHESTA:
+			if (!info->shared)
+			  continue;
+
+		      case R_PPC64_TPREL64:
+		      case R_PPC64_DTPMOD64:
+		      case R_PPC64_DTPREL64:
+		      case R_PPC64_ADDR64:
+		      case R_PPC64_REL30:
+		      case R_PPC64_REL32:
+		      case R_PPC64_REL64:
+		      case R_PPC64_ADDR14:
+		      case R_PPC64_ADDR14_BRNTAKEN:
+		      case R_PPC64_ADDR14_BRTAKEN:
+		      case R_PPC64_ADDR16:
+		      case R_PPC64_ADDR16_DS:
+		      case R_PPC64_ADDR16_HA:
+		      case R_PPC64_ADDR16_HI:
+		      case R_PPC64_ADDR16_HIGHER:
+		      case R_PPC64_ADDR16_HIGHERA:
+		      case R_PPC64_ADDR16_HIGHEST:
+		      case R_PPC64_ADDR16_HIGHESTA:
+		      case R_PPC64_ADDR16_LO:
+		      case R_PPC64_ADDR16_LO_DS:
+		      case R_PPC64_ADDR24:
+		      case R_PPC64_ADDR32:
+		      case R_PPC64_UADDR16:
+		      case R_PPC64_UADDR32:
+		      case R_PPC64_UADDR64:
+		      case R_PPC64_TOC:
+			break;
+		      }
+
+		    r_symndx = ELF64_R_SYM (rel->r_info);
+		    if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
+				    r_symndx, ibfd))
+		      goto error_ret;
+
+		    if ((info->shared
+			 && (MUST_BE_DYN_RELOC (r_type)
+			     || (h != NULL
+				 && (!info->symbolic
+				     || h->root.type == bfd_link_hash_defweak
+				     || !h->def_regular))))
+			|| (ELIMINATE_COPY_RELOCS
+			    && !info->shared
+			    && h != NULL
+			    && (h->root.type == bfd_link_hash_defweak
+				|| !h->def_regular)))
+		      ;
+		    else
+		      continue;
+
+		    if (h != NULL)
+		      head = &((struct ppc_link_hash_entry *) h)->dyn_relocs;
+		    else
+		      {
+			if (sym_sec == NULL)
+			  goto error_ret;
+
+			head = ((struct ppc_dyn_relocs **)
+				&elf_section_data (sym_sec)->local_dynrel);
+		      }
+		    for (p = *head; p != NULL; p = p->next)
+		      if (p->sec == toc)
+			{
+			  p->count -= 1;
+			  if (!MUST_BE_DYN_RELOC (r_type))
+			    p->pc_count -= 1;
+			  break;
+			}
+		  }
+
 	      toc->reloc_count = wrel - relstart;
 	      sz = elf_section_data (toc)->rel_hdr.sh_entsize;
 	      elf_section_data (toc)->rel_hdr.sh_size = toc->reloc_count * sz;

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Binutils mailing list