[committed] hppa64: Fix relocation handling for global data and a couple of thinkos

John David Anglin dave.anglin@bell.net
Wed Oct 8 21:21:02 GMT 2025


Committed to master.

There remains one big problem with 64-bit ld o hppa.  There are spurious
R_PARISC_NONE relocations at the end of most RELA sections in shared
libraries.  This makes these shared libraries unusable on hpux.  For
example,

[...]
8000000000004a20  022d00000082 R_PARISC_EPLT     400000000001002c .__subvti3 + 0
000000000000  000000000000 R_PARISC_NONE                        0
000000000000  000000000000 R_PARISC_NONE                        0
000000000000  000000000000 R_PARISC_NONE                        0
000000000000  000000000000 R_PARISC_NONE                        0
000000000000  000000000000 R_PARISC_NONE                        0
000000000000  000000000000 R_PARISC_NONE                        0
000000000000  000000000000 R_PARISC_NONE                        0
000000000000  000000000000 R_PARISC_NONE                        0
000000000000  000000000000 R_PARISC_NONE                        0
000000000000  000000000000 R_PARISC_NONE                        0
000000000000  000000000000 R_PARISC_NONE                        0
000000000000  000000000000 R_PARISC_NONE                        0

Relocation section '.rela.plt' at offset 0xc3c0 contains 41 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
8000000000004b00  007300000081 R_PARISC_IPLT     0000000000000000 _U_Qfcnvxf_dbl_to_quad + 0
[...]

Still trying to figure out how this happens.  I know we don't directly add any R_PARISC_NONE
relocations.  The .rela.opd section size doesn't seem to be a multiple of OPD_ENTRY_SIZE (0x20):

  [ 7] .rela.opd         RELA             400000000000b968  0000a968
       0000000000001a58  0000000000000018  AI       3    21     8

So far, I haven't figured out how to get rid of them.

Dave
---

hppa64: Fix relocation handling for global data and a couple of thinkos

This fixes relocation handling in situations where hh->owner and
hh->sym_indx were not initialized.

2025-10-08  John David Anglin  <danglin@gcc.gnu.org>

bfd/ChangeLog:

	PR binutils/6511
	* elf64-hppa.c (global_sym_index): New from ia64.
	(elf64_hppa_check_relocs): Only set hh->eh.ref_regular if we
	have a regular definition.
	(elf64_hppa_check_relocs): Add missing NEED_DYNREL to need_entry
	assignment.
	(elf64_hppa_check_relocs): Stash symbol index and section
	earlier.
	(allocate_global_data_dlt): Initialize hh->owner and hh->sym_indx
	if not initialized.
	(allocate_global_data_opd): Likewise.  Remove redundant checks
	for NULL hh.
	(allocate_dynrel_entries): Check for discarded
	hppa_info->other_rel_sec section.  Add assert rent->sec->owner
	== hh->owner.
	(elf64_hppa_finalize_dynreloc): Check for discarded
	hppa_info->other_rel_sec section.
	(elf_hppa_final_link_relocate): Return bfd_reloc_ok if we
	have R_PARISC_NONE relocation.

diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c
index 57de68c9b07..05bb7f125b7 100644
--- a/bfd/elf64-hppa.c
+++ b/bfd/elf64-hppa.c
@@ -247,6 +247,24 @@ static bool get_stub
 static int elf64_hppa_elf_get_symbol_type
   (Elf_Internal_Sym *, int);
 
+/* Search for the index of a global symbol in it's defining object file.  */
+
+static long
+global_sym_index (struct elf_link_hash_entry *h)
+{
+  struct elf_link_hash_entry **p;
+  bfd *obj;
+
+  BFD_ASSERT (h->root.type == bfd_link_hash_defined
+	      || h->root.type == bfd_link_hash_defweak);
+
+  obj = h->root.u.def.section->owner;
+  for (p = elf_sym_hashes (obj); *p != h; ++p)
+    continue;
+
+  return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
+}
+
 /* Initialize an entry in the link hash table.  */
 
 static struct bfd_hash_entry *
@@ -641,7 +659,10 @@ elf64_hppa_check_relocs (bfd *abfd,
 
 	  /* PR15323, ref flags aren't set for references in the same
 	     object.  */
-	  hh->eh.ref_regular = 1;
+	  if (!hh->eh.root.linker_def && !hh->eh.root.ldscript_def)
+	    hh->eh.ref_regular = 1;
+	  else
+	    hh = NULL;
 	}
       else
 	hh = NULL;
@@ -744,7 +765,7 @@ elf64_hppa_check_relocs (bfd *abfd,
 	case R_PARISC_LTOFF_FPTR16WF:
 	case R_PARISC_LTOFF_FPTR16DF:
 	  if (bfd_link_pic (info) || maybe_dynamic)
-	    need_entry = (NEED_DLT | NEED_OPD | NEED_PLT);
+	    need_entry = (NEED_DLT | NEED_OPD | NEED_PLT | NEED_DYNREL);
 	  else
 	    need_entry = (NEED_DLT | NEED_OPD | NEED_PLT);
 	  dynrel_type = R_PARISC_FPTR64;
@@ -762,9 +783,7 @@ elf64_hppa_check_relocs (bfd *abfd,
 	/* Add more cases as needed.  */
 	}
 
-      if (!need_entry)
-	continue;
-
+      /* We may need this information later for OPD.  */
       if (hh)
 	{
 	  /* Stash away enough information to be able to find this symbol
@@ -773,6 +792,9 @@ elf64_hppa_check_relocs (bfd *abfd,
 	  hh->sym_indx = r_symndx;
 	}
 
+      if (!need_entry)
+	continue;
+
       /* Create what's needed.  */
       if (need_entry & NEED_DLT)
 	{
@@ -969,10 +991,14 @@ allocate_global_data_dlt (struct elf_link_hash_entry *eh, void *data)
 	     against it.  */
 	  if (eh->dynindx == -1 && eh->type != STT_PARISC_MILLI)
 	    {
-	      bfd *owner = eh->root.u.def.section->owner;
+	      if (!hh->owner)
+		{
+		  hh->owner = eh->root.u.def.section->owner;
+		  hh->sym_indx = global_sym_index (eh);
+		}
 
 	      if (! (bfd_elf_link_record_local_dynamic_symbol
-		     (x->info, owner, hh->sym_indx)))
+		     (x->info, hh->owner, hh->sym_indx)))
 		return false;
 	    }
 	}
@@ -1050,33 +1076,37 @@ allocate_global_data_opd (struct elf_link_hash_entry *eh, void *data)
     {
       /* We never need an opd entry for a symbol which is not
 	 defined by this output file.  */
-      if (hh && (hh->eh.root.type == bfd_link_hash_undefined
-		 || hh->eh.root.type == bfd_link_hash_undefweak
-		 || hh->eh.root.u.def.section->output_section == NULL))
-	hh->want_opd = 0;
+      if (hh->eh.root.type == bfd_link_hash_undefined
+	  || hh->eh.root.type == bfd_link_hash_undefweak
+	  || hh->eh.root.u.def.section->output_section == NULL)
+	{
+	  hh->want_opd = 0;
+	  return true;
+	}
 
       /* If we are creating a shared library, took the address of a local
 	 function or might export this function from this object file, then
 	 we have to create an opd descriptor.  */
-      else if (bfd_link_pic (x->info)
-	       || hh == NULL
-	       || (hh->eh.dynindx == -1 && hh->eh.type != STT_PARISC_MILLI)
-	       || (hh->eh.root.type == bfd_link_hash_defined
-		   || hh->eh.root.type == bfd_link_hash_defweak))
+      if (bfd_link_pic (x->info)
+	  || (hh->eh.dynindx == -1 && hh->eh.type != STT_PARISC_MILLI)
+	  || hh->eh.root.type == bfd_link_hash_defined
+	  || hh->eh.root.type == bfd_link_hash_defweak)
 	{
 	  /* If we are creating a shared library, then we will have to
 	     create a runtime relocation for the symbol to properly
 	     initialize the .opd entry.  Make sure the symbol gets
 	     added to the dynamic symbol table.  */
-	  if (bfd_link_pic (x->info)
-	      && (hh == NULL || (hh->eh.dynindx == -1)))
+	  if (bfd_link_pic (x->info) && hh->eh.dynindx == -1)
 	    {
-	      bfd *owner;
 	      /* PR 6511: Default to using the dynamic symbol table.  */
-	      owner = (hh->owner ? hh->owner: eh->root.u.def.section->owner);
+	      if (!hh->owner)
+		{
+		  hh->owner = eh->root.u.def.section->owner;
+		  hh->sym_indx = global_sym_index (eh);
+		}
 
 	      if (!bfd_elf_link_record_local_dynamic_symbol
-		    (x->info, owner, hh->sym_indx))
+		    (x->info, hh->owner, hh->sym_indx))
 		return false;
 	    }
 
@@ -1419,15 +1449,18 @@ allocate_dynrel_entries (struct elf_link_hash_entry *eh, void *data)
       if (!shared && rent->type == R_PARISC_FPTR64 && hh->want_opd)
 	continue;
 
-      hppa_info->other_rel_sec->size += sizeof (Elf64_External_Rela);
+      if (!discarded_section (hppa_info->other_rel_sec))
+	hppa_info->other_rel_sec->size += sizeof (Elf64_External_Rela);
 
-      /* Make sure this symbol gets into the dynamic symbol table if it is
-	 not already recorded.  ?!? This should not be in the loop since
-	 the symbol need only be added once.  */
+      /* Make sure this symbol gets into the dynamic symbol table if
+	 it is not already recorded.  */
       if (eh->dynindx == -1 && eh->type != STT_PARISC_MILLI)
-	if (!bfd_elf_link_record_local_dynamic_symbol
-	    (x->info, rent->sec->owner, hh->sym_indx))
-	  return false;
+	{
+	  BFD_ASSERT (rent->sec->owner == hh->owner);
+	  if (!bfd_elf_link_record_local_dynamic_symbol
+		(x->info, hh->owner, hh->sym_indx))
+	    return false;
+	}
     }
 
   /* Take care of the GOT and PLT relocations.  */
@@ -2293,15 +2326,18 @@ elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
   if (!dynamic_symbol && !bfd_link_pic (info))
     return true;
 
+  hppa_info = hppa_link_hash_table (info);
+  if (hppa_info == NULL)
+    return false;
+
+  if (discarded_section (hppa_info->other_rel_sec))
+    return true;
+
   if (hh->reloc_entries)
     {
       struct elf64_hppa_dyn_reloc_entry *rent;
       int dynindx;
 
-      hppa_info = hppa_link_hash_table (info);
-      if (hppa_info == NULL)
-	return false;
-
       /* We may need to do a relocation against a local symbol, in
 	 which case we have to look up it's dynamic symbol index off
 	 the local symbol hash table.  */
@@ -3162,7 +3198,7 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
   switch (r_type)
     {
     case R_PARISC_NONE:
-      break;
+      return bfd_reloc_ok;
 
     /* Basic function call support.
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20251008/2c75ca81/attachment-0001.sig>


More information about the Binutils mailing list