Adding hplt to elf_link_hash_table

Richard Sandiford richard@codesourcery.com
Sat Feb 25 01:39:00 GMT 2006


elf_link_hash_table has a "hgot" field that stores the entry for
_GLOBAL_OFFSET_TABLE_.  The elf32-ppc.c and elf32-i386.c extensions
also have a "hplt" field for _PROCEDURE_LINKAGE_TABLE_, which they
use for VxWorks.

I'm soon going to submit equivalent user-mode VxWorks support for ARM,
and there are other targets to come, so would it be OK to have "hplt"
in the common elf_link_hash_table, alongside "hgot"?

This patch does that, and removes the now-redundant "hgot" field
from elf_i386_link_hash_table.  Tested individually on i586-vxworks
and on i686-linux-gnu with --enable-targets=all --enable-64-bit-bfd.
OK to install?

BTW, I notice that elf32-ppc.c uses:

  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
      || (!htab->is_vxworks
	  && (h == htab->elf.hgot
	      || strcmp (h->root.root.string,
			 "_PROCEDURE_LINKAGE_TABLE_") == 0)))
    ...

whereas most targets use string comparisons.  Would you prefer
all targets to use hash entry comparisons, and do it for both
_GLOBAL_OFFSET_TABLE_ and _PROCEDURE_LINKAGE_TABLE_?
If so, I'll submit a follow-up patch.

Richard


bfd/
	* elf-bfd.h (elf_link_hash_table): Add hplt field.
	* elflink.c (_bfd_elf_create_dynamic_sections): Initialize it.
	* elf-m10300.c (_bfd_mn10300_elf_create_got_section): Likewise.
	* elf32-frv.c (_frv_create_got_section): Likewise.
	* elf32-m32r.c (m32r_elf_create_dynamic_sections): Likewise.
	* elf32-sh.c (sh_elf_create_dynamic_sections): Likewise.
	* elf64-alpha.c (elf64_alpha_create_dynamic_sections): Likewise.
	* elf64-sh64.c (sh64_elf64_create_dynamic_sections): Likewise.
	* elf32-i386.c (elf_i386_link_hash_table): Remove hgot and hplt.
	(elf_i386_link_hash_table_create): Don't initialize them.
	(elf_i386_size_dynamic_sections): Use the generic ELF hplt and
	hgot fields.
	(elf_i386_finish_dynamic_symbol): Likewise.
	* elf32-ppc.c (ppc_elf_link_hash_table): Remove hplt.
	(ppc_elf_size_dynamic_sections): Use the generic ELF hplt fields.
	(ppc_elf_finish_dynamic_symbol): Likewise.
	
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.203
diff -u -p -r1.203 elf-bfd.h
--- bfd/elf-bfd.h 24 Feb 2006 15:47:24 -0000 1.203
+++ bfd/elf-bfd.h 24 Feb 2006 17:23:03 -0000
@@ -378,6 +378,9 @@ struct elf_link_hash_table
   /* The _GLOBAL_OFFSET_TABLE_ symbol.  */
   struct elf_link_hash_entry *hgot;
 
+  /* The _PROCEDURE_LINKAGE_TABLE_ symbol.  */
+  struct elf_link_hash_entry *hplt;
+
   /* A pointer to information used to merge SEC_MERGE sections.  */
   void *merge_info;
 
Index: bfd/elf-m10300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-m10300.c,v
retrieving revision 1.70
diff -u -p -r1.70 elf-m10300.c
--- bfd/elf-m10300.c 25 Aug 2005 02:32:09 -0000 1.70
+++ bfd/elf-m10300.c 24 Feb 2006 17:23:04 -0000
@@ -582,10 +582,14 @@ _bfd_mn10300_elf_create_got_section (abf
 
   /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
      .plt section.  */
-  if (bed->want_plt_sym
-      && !_bfd_elf_define_linkage_sym (abfd, info, s,
-				       "_PROCEDURE_LINKAGE_TABLE_"))
-    return FALSE;
+  if (bed->want_plt_sym)
+    {
+      h = _bfd_elf_define_linkage_sym (abfd, info, s,
+				       "_PROCEDURE_LINKAGE_TABLE_");
+      elf_hash_table (info)->hplt = h;
+      if (h == NULL)
+	return FALSE;
+    }
 
   s = bfd_make_section_with_flags (abfd, ".got", flags);
   if (s == NULL
Index: bfd/elf32-frv.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-frv.c,v
retrieving revision 1.44
diff -u -p -r1.44 elf32-frv.c
--- bfd/elf32-frv.c 17 Feb 2006 18:08:00 -0000 1.44
+++ bfd/elf32-frv.c 24 Feb 2006 17:23:05 -0000
@@ -4398,10 +4398,14 @@ _frv_create_got_section (bfd *abfd, stru
 
   /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
      .plt section.  */
-  if (bed->want_plt_sym
-      && !_bfd_elf_define_linkage_sym (abfd, info, s,
-				       "_PROCEDURE_LINKAGE_TABLE_"))
-    return FALSE;
+  if (bed->want_plt_sym)
+    {
+      h = _bfd_elf_define_linkage_sym (abfd, info, s,
+				       "_PROCEDURE_LINKAGE_TABLE_");
+      elf_hash_table (info)->hplt = h;
+      if (h == NULL)
+	return FALSE;
+    }
 
   /* FRV-specific: we want rel relocations for the plt.  */
   s = bfd_make_section_with_flags (abfd, ".rel.plt",
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.152
diff -u -p -r1.152 elf32-i386.c
--- bfd/elf32-i386.c 21 Feb 2006 01:51:58 -0000 1.152
+++ bfd/elf32-i386.c 24 Feb 2006 17:23:06 -0000
@@ -647,9 +647,6 @@ struct elf_i386_link_hash_table
   /* The (unloaded but important) .rel.plt.unloaded section on VxWorks.  */
   asection *srelplt2;
 
-  /* Short-cuts to frequently used symbols for VxWorks targets.  */
-  struct elf_link_hash_entry *hgot, *hplt;
-
   /* True if the target system is VxWorks.  */
   int is_vxworks;
 
@@ -739,8 +736,6 @@ elf_i386_link_hash_table_create (bfd *ab
   ret->sym_sec.abfd = NULL;
   ret->is_vxworks = 0;
   ret->srelplt2 = NULL;
-  ret->hgot = NULL;
-  ret->hplt = NULL;
   ret->plt0_pad_byte = 0;
 
   return &ret->elf.root;
@@ -2006,20 +2001,14 @@ elf_i386_size_dynamic_sections (bfd *out
       /* Save the GOT and PLT symbols in the hash table for easy access.
 	 Mark them as having relocations; they might not, but we won't
 	 know for sure until we build the GOT in finish_dynamic_symbol.  */
-
-      htab->hgot = elf_link_hash_lookup (elf_hash_table (info),
-					"_GLOBAL_OFFSET_TABLE_",
-					FALSE, FALSE, FALSE);
-      if (htab->hgot)
-	htab->hgot->indx = -2;
-      htab->hplt = elf_link_hash_lookup (elf_hash_table (info),
-					"_PROCEDURE_LINKAGE_TABLE_",
-					FALSE, FALSE, FALSE);
-      if (htab->hplt)
-	htab->hplt->indx = -2;
-
-      if (htab->is_vxworks && htab->hplt && htab->splt->flags & SEC_CODE)
-	htab->hplt->type = STT_FUNC;
+      if (htab->elf.hgot)
+	htab->elf.hgot->indx = -2;
+      if (htab->elf.hplt)
+	{
+	  htab->elf.hplt->indx = -2;
+	  if (htab->splt->flags & SEC_CODE)
+	    htab->elf.hplt->type = STT_FUNC;
+	}
     }
 
   /* Allocate global sym .plt and .got entries, and space for global
@@ -2055,7 +2044,7 @@ elf_i386_size_dynamic_sections (bfd *out
 	     we've exported dynamic symbols from them we must leave them.
 	     It's too late to tell BFD to get rid of the symbols.  */
 
-	  if (htab->hplt != NULL)
+	  if (htab->elf.hplt != NULL)
 	    strip_section = FALSE;
 	}
       else if (strncmp (bfd_get_section_name (dynobj, s), ".rel", 4) == 0)
@@ -3524,7 +3513,7 @@ elf_i386_finish_dynamic_symbol (bfd *out
 	      rel.r_offset = (htab->splt->output_section->vma
 			      + htab->splt->output_offset
 			      + h->plt.offset + 2),
-	      rel.r_info = ELF32_R_INFO (htab->hgot->indx, R_386_32);
+	      rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
 	      bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
 
 	      /* Create the R_386_32 relocation referencing the beginning of
@@ -3532,7 +3521,7 @@ elf_i386_finish_dynamic_symbol (bfd *out
 	      rel.r_offset = (htab->sgotplt->output_section->vma
 			      + htab->sgotplt->output_offset
 			      + got_offset);
-	      rel.r_info = ELF32_R_INFO (htab->hplt->indx, R_386_32);
+	      rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32);
 	      bfd_elf32_swap_reloc_out (output_bfd, &rel,
 	      loc + sizeof (Elf32_External_Rel));
 	    }
@@ -3786,28 +3775,21 @@ elf_i386_finish_dynamic_sections (bfd *o
 	      if (htab->is_vxworks)
 		{
 		  Elf_Internal_Rela rel;
-		  struct elf_link_hash_entry *hgot;
 
-		  /* The VxWorks GOT is relocated by the dynamic linker.
-		     Therefore, we must emit relocations rather than
-		     simply computing the values now.  */
-		  hgot = elf_link_hash_lookup (elf_hash_table (info),
-					       "_GLOBAL_OFFSET_TABLE_",
-					       FALSE, FALSE, FALSE);
 		  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4.
 		     On IA32 we use REL relocations so the addend goes in
 		     the PLT directly.  */
 		  rel.r_offset = (htab->splt->output_section->vma
 				  + htab->splt->output_offset
 				  + 2);
-		  rel.r_info = ELF32_R_INFO (hgot->indx, R_386_32);
+		  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
 		  bfd_elf32_swap_reloc_out (output_bfd, &rel,
 					    htab->srelplt2->contents);
 		  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
 		  rel.r_offset = (htab->splt->output_section->vma
 				  + htab->splt->output_offset
 				  + 8);
-		  rel.r_info = ELF32_R_INFO (hgot->indx, R_386_32);
+		  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
 		  bfd_elf32_swap_reloc_out (output_bfd, &rel,
 					    htab->srelplt2->contents +
 					    sizeof (Elf32_External_Rel));
@@ -3835,12 +3817,12 @@ elf_i386_finish_dynamic_sections (bfd *o
 		{
 		  Elf_Internal_Rela rel;
 		  bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
-		  rel.r_info = ELF32_R_INFO (htab->hgot->indx, R_386_32);
+		  rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
 		  bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
 		  p += sizeof (Elf32_External_Rel);
 
 		  bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
-		  rel.r_info = ELF32_R_INFO (htab->hplt->indx, R_386_32);
+		  rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32);
 		  bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
 		  p += sizeof (Elf32_External_Rel);
 		}
Index: bfd/elf32-m32r.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m32r.c,v
retrieving revision 1.77
diff -u -p -r1.77 elf32-m32r.c
--- bfd/elf32-m32r.c 21 Feb 2006 01:51:59 -0000 1.77
+++ bfd/elf32-m32r.c 24 Feb 2006 17:23:07 -0000
@@ -1668,6 +1668,7 @@ m32r_elf_create_dynamic_sections (bfd *a
       h = (struct elf_link_hash_entry *) bh;
       h->def_regular = 1;
       h->type = STT_OBJECT;
+      htab->root.hplt = h;
 
       if (info->shared
           && ! bfd_elf_link_record_dynamic_symbol (info, h))
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.187
diff -u -p -r1.187 elf32-ppc.c
--- bfd/elf32-ppc.c 17 Feb 2006 12:52:58 -0000 1.187
+++ bfd/elf32-ppc.c 24 Feb 2006 17:23:09 -0000
@@ -2365,9 +2365,6 @@ struct ppc_elf_link_hash_table
   /* The .got.plt section (VxWorks only)*/
   asection *sgotplt;
 
-  /* Short-cuts to frequently used symbols on VxWorks targets.  */
-  struct elf_link_hash_entry *hplt;
-
   /* True if the target system is VxWorks.  */
   int is_vxworks;
 
@@ -4766,17 +4763,14 @@ ppc_elf_size_dynamic_sections (bfd *outp
 	 Mark GOT and PLT syms as having relocations; they might not,
 	 but we won't know for sure until we build the GOT in
 	 finish_dynamic_symbol.  */
-
       if (htab->elf.hgot)
 	htab->elf.hgot->indx = -2;
-      htab->hplt = elf_link_hash_lookup (elf_hash_table (info),
-					 "_PROCEDURE_LINKAGE_TABLE_",
-					 FALSE, FALSE, FALSE);
-      if (htab->hplt)
-	htab->hplt->indx = -2;
-      /* If the PLT is executable then give the symbol function type.  */
-      if (htab->hplt && htab->plt->flags & SEC_CODE)
-       htab->hplt->type = STT_FUNC;
+      if (htab->elf.hplt)
+	{
+	  htab->elf.hplt->indx = -2;
+	  if (htab->plt->flags & SEC_CODE)
+	    htab->elf.hplt->type = STT_FUNC;
+	}
     }
 
   /* Allocate space for global sym dynamic relocs.  */
@@ -4867,7 +4861,7 @@ ppc_elf_size_dynamic_sections (bfd *outp
 	  /* We'd like to strip these sections if they aren't needed, but if
 	     we've exported dynamic symbols from them we must leave them.
 	     It's too late to tell BFD to get rid of the symbols.  */
-	  if ((s == htab->plt || s == htab->got) && htab->hplt != NULL)
+	  if ((s == htab->plt || s == htab->got) && htab->elf.hplt != NULL)
 	    strip_section = FALSE;
 	  /* Strip this section if we don't need it; see the
 	     comment below.  */
@@ -6880,7 +6874,7 @@ ppc_elf_finish_dynamic_symbol (bfd *outp
 		    rela.r_offset = (htab->sgotplt->output_section->vma
 				     + htab->sgotplt->output_offset
 				     + got_offset);
-		    rela.r_info = ELF32_R_INFO (htab->hplt->indx,
+		    rela.r_info = ELF32_R_INFO (htab->elf.hplt->indx,
 						R_PPC_ADDR32);
 		    rela.r_addend = ent->plt.offset + 16;
 		    bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
@@ -7248,7 +7242,7 @@ ppc_elf_finish_dynamic_sections (bfd *ou
 	      loc += sizeof (Elf32_External_Rela);
 
 	      bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
-	      rel.r_info = ELF32_R_INFO (htab->hplt->indx, R_PPC_ADDR32);
+	      rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_PPC_ADDR32);
 	      bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
 	      loc += sizeof (Elf32_External_Rela);
 	    }
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.133
diff -u -p -r1.133 elf32-sh.c
--- bfd/elf32-sh.c 21 Feb 2006 01:51:58 -0000 1.133
+++ bfd/elf32-sh.c 24 Feb 2006 17:23:11 -0000
@@ -3726,6 +3726,7 @@ sh_elf_create_dynamic_sections (bfd *abf
       h = (struct elf_link_hash_entry *) bh;
       h->def_regular = 1;
       h->type = STT_OBJECT;
+      htab->root.hplt = h;
 
       if (info->shared
 	  && ! bfd_elf_link_record_dynamic_symbol (info, h))
Index: bfd/elf64-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-alpha.c,v
retrieving revision 1.147
diff -u -p -r1.147 elf64-alpha.c
--- bfd/elf64-alpha.c 15 Aug 2005 15:39:08 -0000 1.147
+++ bfd/elf64-alpha.c 24 Feb 2006 17:23:12 -0000
@@ -1244,8 +1244,10 @@ elf64_alpha_create_dynamic_sections (bfd
 
   /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
      .plt section.  */
-  if (!_bfd_elf_define_linkage_sym (abfd, info, s,
-				    "_PROCEDURE_LINKAGE_TABLE_"))
+  h = _bfd_elf_define_linkage_sym (abfd, info, s,
+				   "_PROCEDURE_LINKAGE_TABLE_");
+  elf_hash_table (info)->hplt = h;
+  if (h == NULL)
     return FALSE;
 
   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
Index: bfd/elf64-sh64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-sh64.c,v
retrieving revision 1.64
diff -u -p -r1.64 elf64-sh64.c
--- bfd/elf64-sh64.c 25 Aug 2005 02:32:11 -0000 1.64
+++ bfd/elf64-sh64.c 24 Feb 2006 17:23:13 -0000
@@ -3240,6 +3240,7 @@ sh64_elf64_create_dynamic_sections (bfd 
       h = (struct elf_link_hash_entry *) bh;
       h->def_regular = 1;
       h->type = STT_OBJECT;
+      elf_hash_table (info)->hplt = h;
 
       if (info->shared
 	  && ! bfd_elf_link_record_dynamic_symbol (info, h))
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.203
diff -u -p -r1.203 elflink.c
--- bfd/elflink.c 24 Feb 2006 15:47:24 -0000 1.203
+++ bfd/elflink.c 24 Feb 2006 17:23:15 -0000
@@ -263,6 +263,7 @@ bfd_boolean
 _bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
 {
   flagword flags, pltflags;
+  struct elf_link_hash_entry *h;
   asection *s;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
@@ -288,10 +289,14 @@ _bfd_elf_create_dynamic_sections (bfd *a
 
   /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
      .plt section.  */
-  if (bed->want_plt_sym
-      && !_bfd_elf_define_linkage_sym (abfd, info, s,
-				       "_PROCEDURE_LINKAGE_TABLE_"))
-    return FALSE;
+  if (bed->want_plt_sym)
+    {
+      h = _bfd_elf_define_linkage_sym (abfd, info, s,
+				       "_PROCEDURE_LINKAGE_TABLE_");
+      elf_hash_table (info)->hplt = h;
+      if (h == NULL)
+	return FALSE;
+    }
 
   s = bfd_make_section_with_flags (abfd,
 				   (bed->default_use_rela_p



More information about the Binutils mailing list