From d6ce0aa3f877dd4475f77033496383c66383d69b Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Tue, 5 May 2026 14:51:40 -0400 Subject: [PATCH] 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 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. --- bfd/elf64-hppa.c | 59 ++++++++++++++++++++++------------- ld/testsuite/ld-elf/group8a.d | 2 +- ld/testsuite/ld-elf/group8b.d | 2 +- ld/testsuite/ld-elf/group9a.d | 2 +- ld/testsuite/ld-elf/group9b.d | 2 +- ld/testsuite/ld-elf/pr12851.d | 2 +- ld/testsuite/ld-elf/pr22677.d | 2 +- 7 files changed, 44 insertions(+), 27 deletions(-) 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?.* -- 2.47.3