[PATCH] ld: Add ehdr_start to bfd_link_hash_entry

Alan Modra amodra@gmail.com
Wed Jan 5 01:57:54 GMT 2022


On Sat, Jan 01, 2022 at 07:37:19PM -0800, H.J. Lu via Binutils wrote:
> __ehdr_start is a special symbol which is undefined during link.  It
> becomes defined almost at the last minute if it is referenced.  Add
> ehdr_start to bfd_link_hash_entry for __ehdr_start so that ELF linker
> can properly handle it.

We make some effort in ldelf_before_allocation to handle __ehdr_start
for bfd_elf_size_dynamic_sections by defining it early.  Where else do
we need special handling?

Hmm, I'm guessing for your DT_RELR support.  

I wonder if we can't revise the existing __ehdr_start hacks.  I think
I'd prefer that rather than adding another special case.  Let's see
if we can make this patch unnecessary.  Something along the lines of
the following, which currently hits an error on x86_64.

failed with: <./ld-new: tmpdir/ehdr_start.o(.rodata+0): reloc against `__ehdr_start': error 6>, no expected output
FAIL: ld-elf/ehdr_start-shared


diff --git a/bfd/elflink.c b/bfd/elflink.c
index 24acb37925c..49652724e4c 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -510,6 +510,10 @@ bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info,
       const char *name;
       size_t indx;
 
+      /* Linker defined symbols are not dynamic.  */
+      if (h->root.linker_def)
+	return true;
+
       if (h->root.type == bfd_link_hash_defined
 	  || h->root.type == bfd_link_hash_defweak)
 	{
diff --git a/ld/ldelf.c b/ld/ldelf.c
index 00caa6bef47..c31787fb30a 100644
--- a/ld/ldelf.c
+++ b/ld/ldelf.c
@@ -1563,52 +1563,19 @@ ldelf_before_allocation (char *audit, char *depaudit,
   const char *rpath;
   asection *sinterp;
   bfd *abfd;
-  struct bfd_link_hash_entry *ehdr_start = NULL;
-  unsigned char ehdr_start_save_type = 0;
-  char ehdr_start_save_u[sizeof ehdr_start->u
-			 - sizeof ehdr_start->u.def.next] = "";
 
   if (is_elf_hash_table (link_info.hash))
     {
       _bfd_elf_tls_setup (link_info.output_bfd, &link_info);
 
-      /* Make __ehdr_start hidden if it has been referenced, to
-	 prevent the symbol from being dynamic.  */
       if (!bfd_link_relocatable (&link_info))
 	{
 	  struct elf_link_hash_table *htab = elf_hash_table (&link_info);
 	  struct elf_link_hash_entry *h
 	    = elf_link_hash_lookup (htab, "__ehdr_start", false, false, true);
 
-	  /* Only adjust the export class if the symbol was referenced
-	     and not defined, otherwise leave it alone.  */
-	  if (h != NULL
-	      && (h->root.type == bfd_link_hash_new
-		  || h->root.type == bfd_link_hash_undefined
-		  || h->root.type == bfd_link_hash_undefweak
-		  || h->root.type == bfd_link_hash_common))
-	    {
-	      const struct elf_backend_data *bed;
-	      bed = get_elf_backend_data (link_info.output_bfd);
-	      (*bed->elf_backend_hide_symbol) (&link_info, h, true);
-	      if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
-		h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
-	      /* Don't leave the symbol undefined.  Undefined hidden
-		 symbols typically won't have dynamic relocations, but
-		 we most likely will need dynamic relocations for
-		 __ehdr_start if we are building a PIE or shared
-		 library.  */
-	      ehdr_start = &h->root;
-	      ehdr_start_save_type = ehdr_start->type;
-	      memcpy (ehdr_start_save_u,
-		      (char *) &ehdr_start->u + sizeof ehdr_start->u.def.next,
-		      sizeof ehdr_start_save_u);
-	      ehdr_start->type = bfd_link_hash_defined;
-	      /* It will be converted to section-relative later.  */
-	      ehdr_start->rel_from_abs = 1;
-	      ehdr_start->u.def.section = bfd_abs_section_ptr;
-	      ehdr_start->u.def.value = 0;
-	    }
+	  if (h != NULL)
+	    h->root.linker_def = 1;
 	}
 
       /* If we are going to make any variable assignments, we need to
@@ -1724,16 +1691,6 @@ ldelf_before_allocation (char *audit, char *depaudit,
 
   if (!bfd_elf_size_dynsym_hash_dynstr (link_info.output_bfd, &link_info))
     einfo (_("%F%P: failed to set dynamic section sizes: %E\n"));
-
-  if (ehdr_start != NULL)
-    {
-      /* If we twiddled __ehdr_start to defined earlier, put it back
-	 as it was.  */
-      ehdr_start->type = ehdr_start_save_type;
-      memcpy ((char *) &ehdr_start->u + sizeof ehdr_start->u.def.next,
-	      ehdr_start_save_u,
-	      sizeof ehdr_start_save_u);
-    }
 }
 /* Try to open a dynamic archive.  This is where we know that ELF
    dynamic libraries have an extension of .so (or .sl on oddball systems


-- 
Alan Modra
Australia Development Lab, IBM


More information about the Binutils mailing list