[committed] hppa64: Disable -gc-section support on hppa*64*-*-hpux*

Message ID afo9vUauRLAvdR9o@mx3210.local
State New
Headers
Series [committed] hppa64: Disable -gc-section support on hppa*64*-*-hpux* |

Commit Message

John David Anglin May 5, 2026, 6:58 p.m. UTC
  Test on hppa64-hp-hpux11.11 and x86_64-pc-linux-gnu.  Committed to
master.

Dave
---

hppa64: Disable -gc-section support on hppa*64*-*-hpux*

The HP-UX dynamic linker on hppa generates an error if it detects
a dynamic relocation with the R_PARISC_NONE type.  As a result,
there is no way to handle relocations in sections that are garbage
collected.  Although these can mostly be avoided, I think it best
to disable -gc-section support.

2026-05-06  John David Anglin  <danglin@gcc.gnu.org>

bfd/ChangeLog:

	* elf64-hppa.c (elf_hppa_final_link_relocate): Rework
	BFD_ASSERT to only trigger on hpux.  Zero rela if the
	new offset is invalid.
	(elf_backend_can_gc_sections): Set to zero on hpux.
	
ld/ChangeLog:

	* testsuite/ld-elf/group8a.d: xfail hppa*64*-*-hpux*.
	* testsuite/ld-elf/group8b.d: Likewise.
	* testsuite/ld-elf/group9a.d: Likewise.
	* testsuite/ld-elf/group9b.d: Likewise.
	* testsuite/ld-elf/pr12851.d: Likewise.
	* testsuite/ld-elf/pr22677.d: Likewise.
  

Patch

diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c
index 655b0aec0c1..4f405c32f35 100644
--- a/bfd/elf64-hppa.c
+++ b/bfd/elf64-hppa.c
@@ -4052,35 +4052,49 @@  elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
 						     r_symndx) != -1)
 	    {
 	      bfd_vma out_off;
+	      bool skip;
 	      struct elf_link_hash_entry *baseh;
 
 	      out_off = _bfd_elf_section_offset (output_bfd, info,
 						 input_section,
 						 rel->r_offset);
-
-	      BFD_ASSERT (out_off != (bfd_vma) -1 && out_off != (bfd_vma) -2);
-
-	      /* This is the output relocation offset.  */
-	      rela.r_offset = (out_off
-			       + input_section->output_offset
-			       + input_section->output_section->vma);
-
-	      /* Select base segment.  */
-	      if (sym_sec->flags & SEC_READONLY)
-		baseh = hppa_info->text_hash_entry;
+	      skip = out_off == (bfd_vma) -1 || out_off == (bfd_vma) -2;
+
+	      /* If this triggers, we need to skip this relocation or
+		 output a NULL relocation.  Skipping the relocation messes
+		 up the relocation count as we can't detect this case in
+		 elf64_hppa_late_size_sections().  The HP dynamic linker
+		 doesn't like relocations with the R_PARISC_NONE type.
+		 So, we are scuppered.  We need to avoid dynamic relocations
+		 in linkonce sections that may be garbage collected.  */
+	      BFD_ASSERT (!skip || output_bfd->xvec != &hppa_elf64_vec);
+
+	      if (skip)
+		memset (&rela, 0, sizeof (rela));
 	      else
-		baseh = hppa_info->data_hash_entry;
+		{
+		  /* This is the output relocation offset.  */
+		  rela.r_offset = (out_off
+				   + input_section->output_offset
+				   + input_section->output_section->vma);
+
+		  /* Select base segment.  */
+		  if (sym_sec->flags & SEC_READONLY)
+		    baseh = hppa_info->text_hash_entry;
+		  else
+		    baseh = hppa_info->data_hash_entry;
 
-	      sec = baseh->root.u.def.section;
-	      dynindx = baseh->dynindx;
+		  sec = baseh->root.u.def.section;
+		  dynindx = baseh->dynindx;
 
-	      /* Adjust addend using the difference of the symbol's
-		 location and the section symbol's address.  */
-	      rela.r_addend = (value + addend - sec->output_offset
-			       - sec->output_section->vma);
+		  /* Adjust addend using the difference of the symbol's
+		     location and the section symbol's address.  */
+		  rela.r_addend = (value + addend - sec->output_offset
+				   - sec->output_section->vma);
 
-	      /* We need a dynamic relocation for this symbol.  */
-	      rela.r_info = ELF64_R_INFO (dynindx, R_PARISC_DIR64);
+		  /* We need a dynamic relocation for this symbol.  */
+		  rela.r_info = ELF64_R_INFO (dynindx, R_PARISC_DIR64);
+		}
 
 	      s = hppa_info->other_rel_sec;
 	      loc = s->contents;
@@ -4568,7 +4582,7 @@  static const struct elf_size_info hppa64_elf_size_info =
 #define elf_backend_link_output_symbol_hook \
 	elf64_hppa_link_output_symbol_hook
 
-#define elf_backend_can_gc_sections	1
+#define elf_backend_can_gc_sections	0
 #define elf_backend_want_got_plt	0
 #define elf_backend_plt_readonly	0
 #define elf_backend_want_plt_sym	0
@@ -4598,6 +4612,9 @@  static const struct elf_size_info hppa64_elf_size_info =
 #define elf_backend_special_sections	(elf64_hppa_special_sections + 1)
 #undef elf_backend_modify_segment_map
 #undef elf_backend_want_p_paddr_set_to_zero
+
+#undef elf_backend_can_gc_sections
+#define elf_backend_can_gc_sections	1
 #undef elf_backend_want_dynrelro
 #define elf_backend_want_dynrelro	1
 
diff --git a/ld/testsuite/ld-elf/group8a.d b/ld/testsuite/ld-elf/group8a.d
index 09320f6cdf9..34e17636778 100644
--- a/ld/testsuite/ld-elf/group8a.d
+++ b/ld/testsuite/ld-elf/group8a.d
@@ -2,7 +2,7 @@ 
 #ld: -r --gc-sections --entry foo
 #readelf: -g --wide
 # generic linker targets don't support --gc-sections, nor do a bunch of others
-#xfail: [is_generic] mep-*-* mn10200-*-*
+#xfail: [is_generic] hppa*64*-*-hpux* mep-*-* mn10200-*-*
 
 COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains . sections:
    \[Index\]    Name
diff --git a/ld/testsuite/ld-elf/group8b.d b/ld/testsuite/ld-elf/group8b.d
index a3851d00529..acfbd68eb67 100644
--- a/ld/testsuite/ld-elf/group8b.d
+++ b/ld/testsuite/ld-elf/group8b.d
@@ -2,7 +2,7 @@ 
 #ld: -r --gc-sections --entry bar
 #readelf: -g --wide
 # generic linker targets don't support --gc-sections, nor do a bunch of others
-#xfail: [is_generic] mep-*-* mn10200-*-*
+#xfail: [is_generic] hppa*64*-*-hpux* mep-*-* mn10200-*-*
 
 COMDAT group section \[[ 0-9]+\] `.group' \[bar\] contains . sections:
    \[Index\]    Name
diff --git a/ld/testsuite/ld-elf/group9a.d b/ld/testsuite/ld-elf/group9a.d
index 9b481637dd5..4fb7021721b 100644
--- a/ld/testsuite/ld-elf/group9a.d
+++ b/ld/testsuite/ld-elf/group9a.d
@@ -2,7 +2,7 @@ 
 #ld: -r --gc-sections --entry foo
 #readelf: -g --wide
 # generic linker targets don't support --gc-sections, nor do a bunch of others
-#xfail: [is_generic] mep-*-* mn10200-*-*
+#xfail: [is_generic] hppa*64*-*-hpux* mep-*-* mn10200-*-*
 
 COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains . sections:
    \[Index\]    Name
diff --git a/ld/testsuite/ld-elf/group9b.d b/ld/testsuite/ld-elf/group9b.d
index 09cdb1f27cf..08bd6138653 100644
--- a/ld/testsuite/ld-elf/group9b.d
+++ b/ld/testsuite/ld-elf/group9b.d
@@ -2,7 +2,7 @@ 
 #ld: -r --gc-sections --entry bar
 #readelf: -g --wide
 # generic linker targets don't support --gc-sections, nor do a bunch of others
-#xfail: [is_generic] mep-*-* mn10200-*-*
+#xfail: [is_generic] hppa*64*-*-hpux* mep-*-* mn10200-*-*
 
 COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains . sections:
    \[Index\]    Name
diff --git a/ld/testsuite/ld-elf/pr12851.d b/ld/testsuite/ld-elf/pr12851.d
index 9880e4a1ef3..7d606008bb1 100644
--- a/ld/testsuite/ld-elf/pr12851.d
+++ b/ld/testsuite/ld-elf/pr12851.d
@@ -2,7 +2,7 @@ 
 #source: start.s
 #ld: --gc-sections
 #readelf: -s --wide
-#xfail: [is_generic] mep-*-* mn10200-*-*
+#xfail: [is_generic] hppa*64*-*-hpux* mep-*-* mn10200-*-*
 # generic linker targets don't support --gc-sections, nor do a bunch of others
 
 #...
diff --git a/ld/testsuite/ld-elf/pr22677.d b/ld/testsuite/ld-elf/pr22677.d
index f2f21e4c115..4203289dead 100644
--- a/ld/testsuite/ld-elf/pr22677.d
+++ b/ld/testsuite/ld-elf/pr22677.d
@@ -2,7 +2,7 @@ 
 #readelf: -S --wide
 # generic linker targets don't support --gc-sections, nor do a bunch of
 # others.
-#xfail: [is_generic] mep-*-* mn10200-*-*
+#xfail: [is_generic] hppa*64*-*-hpux* mep-*-* mn10200-*-*
 
 #...
   \[[ 0-9]+\] \.preinit_array\.01000[ \t]+PREINIT_ARRAY[ \t0-9a-f]+WA?.*