[binutils-gdb] hppa64: Fix some issues handling dynamic relocaltions

John David Anglin danglin@sourceware.org
Tue Nov 4 21:01:39 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d05b05527b9598a5822e358061f1d59a6db1aa86

commit d05b05527b9598a5822e358061f1d59a6db1aa86
Author: John David Anglin <danglin@gcc.gnu.org>
Date:   Tue Nov 4 16:00:04 2025 -0500

    hppa64: Fix some issues handling dynamic relocaltions
    
    This change fixes the allocation logic in allocate_dynrel_entries and
    elf64_hppa_finalize_dynreloc.  It also fixes addend calculation for
    segment based relocations.
    
    Some applications now link successfully on HP-UX but there are still
    issues with external weak symbols.  This breaks linking with libgcc.
    It looks like we need support for .rela.data.rel.ro, ...
    
    2025-11-04  John David Anglin  <danglin@gcc.gnu.org>
    
    bfd/ChangeLog:
    
            * elf64-hppa.c (allocate_dynrel_entries): Correct hh->want_opd
            if condition.
            (elf64_hppa_finalize_dynreloc): Likewise.  Use symbol address
            instead of OPD address.  Include sec->output_offset in value2
            calculation.
            (elf64_hppa_finalize_opd): Likewise.
            (elf64_hppa_finalize_dlt): Likewise.
            (elf_hppa_final_link_relocate): Fix symbol address calculation.

Diff:
---
 bfd/elf64-hppa.c | 52 ++++++++++++++++++++++++++--------------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c
index 682f1cbd11d..42434b3a2ef 100644
--- a/bfd/elf64-hppa.c
+++ b/bfd/elf64-hppa.c
@@ -1358,8 +1358,8 @@ allocate_dynrel_entries (struct elf_link_hash_entry *eh, void *data)
   for (rent = hh->reloc_entries; rent; rent = rent->next)
     {
       /* Allocate one iff we are building a shared library, the relocation
-	 isn't a R_PARISC_FPTR64, or we don't want an opd entry.  */
-      if (!shared && rent->type == R_PARISC_FPTR64 && hh->want_opd)
+	 isn't a R_PARISC_FPTR64, and we want an opd entry.  */
+      if (!shared && rent->type == R_PARISC_FPTR64 && !hh->want_opd)
 	continue;
 
       if (!discarded_section (hppa_info->other_rel_sec))
@@ -2132,7 +2132,7 @@ elf64_hppa_finalize_opd (struct elf_link_hash_entry *eh, void *data)
 
       /* Compute the base address of the segment with this symbol.  */
       sec = hppa_info->text_hash_entry->root.u.def.section;
-      value2 = sec->output_section->vma;
+      value2 = sec->output_offset + sec->output_section->vma;
 
       /* Compute the difference between the symbol and the text segment
 	 base address.  */
@@ -2226,13 +2226,13 @@ elf64_hppa_finalize_dlt (struct elf_link_hash_entry *eh, void *data)
 	  if (eh->root.u.def.section->flags & SEC_READONLY)
 	    {
 	      sec = hppa_info->text_hash_entry->root.u.def.section;
-	      value2 = sec->output_section->vma;
+	      value2 = sec->output_offset + sec->output_section->vma;
 	      dynindx = hppa_info->text_hash_entry->dynindx;
 	    }
 	  else
 	    {
 	      sec = hppa_info->data_hash_entry->root.u.def.section;
-	      value2 = sec->output_section->vma;
+	      value2 = sec->output_offset + sec->output_section->vma;
 	      dynindx = hppa_info->data_hash_entry->dynindx;
 	    }
 	  rel.r_addend = value - value2;
@@ -2295,9 +2295,9 @@ elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
 	  bfd_byte *loc;
 
 	  /* Allocate one iff we are building a shared library, the relocation
-	     isn't a R_PARISC_FPTR64, or we don't want an opd entry.  */
+	     isn't a R_PARISC_FPTR64, or we want an opd entry.  */
 	  if (!bfd_link_pic (info)
-	      && rent->type == R_PARISC_FPTR64 && hh->want_opd)
+	      && rent->type == R_PARISC_FPTR64 && !hh->want_opd)
 	    continue;
 
 	  /* Create a dynamic relocation for this entry.
@@ -2333,10 +2333,10 @@ elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
 	      asection *sec;
 	      bfd_vma value, value2;
 
-	      /* First compute the address of the opd entry for this symbol.  */
-	      value = (hh->opd_offset
-		       + hppa_info->opd_sec->output_section->vma
-		       + hppa_info->opd_sec->output_offset);
+	      /* Compute the address of the symbol.  */
+	      value = (eh->root.u.def.value
+		       + eh->root.u.def.section->output_section->vma
+		       + eh->root.u.def.section->output_offset);
 
 	      if (hh->eh.dynindx != -1)
 		{
@@ -2346,13 +2346,13 @@ elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
 	      else if (rent->sec->flags & SEC_READONLY)
 		{
 		  sec = hppa_info->text_hash_entry->root.u.def.section;
-		  value2 = sec->output_section->vma;
+		  value2 = sec->output_offset + sec->output_section->vma;
 		  dynindx = hppa_info->text_hash_entry->dynindx;
 		}
 	      else
 		{
 		  sec = hppa_info->data_hash_entry->root.u.def.section;
-		  value2 = sec->output_section->vma;
+		  value2 = sec->output_offset + sec->output_section->vma;
 		  dynindx = hppa_info->data_hash_entry->dynindx;
 		}
 
@@ -2375,13 +2375,13 @@ elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
 	      if (eh->root.u.def.section->flags & SEC_READONLY)
 		{
 		  sec = hppa_info->text_hash_entry->root.u.def.section;
-		  value2 = sec->output_section->vma;
+		  value2 = sec->output_offset + sec->output_section->vma;
 		  dynindx = hppa_info->text_hash_entry->dynindx;
 		}
 	      else
 		{
 		  sec = hppa_info->data_hash_entry->root.u.def.section;
-		  value2 = sec->output_section->vma;
+		  value2 = sec->output_offset + sec->output_section->vma;
 		  dynindx = hppa_info->data_hash_entry->dynindx;
 		}
 	      rel.r_addend = value - value2 + rent->addend;
@@ -3403,11 +3403,11 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
 		    dynindx = hppa_info->data_hash_entry->dynindx;
 		  }
 
-		/* Adjust the value with the difference between the
+		/* Adjust the addend with the difference between the
 		   symbol's address and the base segment's address.  */
-		value += (relocation + addend
-			  - sec->output_offset
-			  - sec->output_section->vma);
+		value = (relocation + addend
+			 - sec->output_offset
+			 - sec->output_section->vma);
 
 		/* The result becomes the addend of the relocation.  */
 		rela.r_addend = value;
@@ -3505,11 +3505,11 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
 		dynindx = hppa_info->data_hash_entry->dynindx;
 	      }
 
-	    /* Adjust value using the difference of the symbol's
+	    /* Adjust addend using the difference of the symbol's
 	       location and the section symbol's address.  */
-	    value += (relocation + addend
-		      - sec->output_offset
-		      - sec->output_section->vma);
+	    value = (relocation + addend
+		     - sec->output_offset
+		     - sec->output_section->vma);
 
 	    /* The result becomes the addend of the relocation.  */
 	    rela.r_addend = value;
@@ -3850,9 +3850,9 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
 
 	    /* Compute the difference between the symbol's address
 	       and the base segment's address.  */
-	    value += (relocation + addend
-		      - sec->output_offset
-		      - sec->output_section->vma);
+	    value = (relocation + addend
+		     - sec->output_offset
+		     - sec->output_section->vma);
 
 	    /* The result becomes the addend of the relocation.  */
 	    rela.r_addend = value;


More information about the Binutils-cvs mailing list