From: Alan Modra Date: Thu, 17 Jul 2025 23:56:10 +0000 (+0930) Subject: RELOC_AGAINST_DISCARDED_SECTION zero size reloc sections X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=129cdfc16433bd755c81357bb2f665ca93edb0b4;p=thirdparty%2Fbinutils-gdb.git RELOC_AGAINST_DISCARDED_SECTION zero size reloc sections For some reason the initial implementation (commit 0672748ac053) of this macro didn't allow discarding of all relocs in a section, perhaps because doing so would require a testsuite change. This patch allows zero size relocation sections to result, and adjusts the testsuite. i386, x86_64, ppc and ppc64 code that avoids a memmove is also changed to allow zero size reloc sections, and arc fixed to actually adjust the reloc section header. --- diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index fbb1cd9e890..c02e34e75ba 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -3287,25 +3287,20 @@ extern asection _bfd_elf_large_com_section; && ((input_section->flags & SEC_DEBUGGING) != 0 \ || elf_section_type (input_section) == SHT_GNU_SFRAME)) \ { \ - Elf_Internal_Shdr *rel_hdr; \ + Elf_Internal_Shdr *rel_hdr \ + = _bfd_elf_single_rel_hdr (input_section->output_section); \ \ - rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); \ + rel_hdr->sh_size -= rel_hdr->sh_entsize; \ + rel_hdr = _bfd_elf_single_rel_hdr (input_section); \ + rel_hdr->sh_size -= rel_hdr->sh_entsize; \ \ - /* Avoid empty output section. */ \ - if (rel_hdr->sh_size > rel_hdr->sh_entsize) \ - { \ - rel_hdr->sh_size -= rel_hdr->sh_entsize; \ - rel_hdr = _bfd_elf_single_rel_hdr (input_section); \ - rel_hdr->sh_size -= rel_hdr->sh_entsize; \ + memmove (rel, rel + count, \ + (relend - rel - count) * sizeof (*rel)); \ \ - memmove (rel, rel + count, \ - (relend - rel - count) * sizeof (*rel)); \ - \ - input_section->reloc_count -= count; \ - relend -= count; \ - rel--; \ - continue; \ - } \ + input_section->reloc_count -= count; \ + relend -= count; \ + rel--; \ + continue; \ } \ \ for (int i_ = 0; i_ < count; i_++) \ diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index 0a6e66569ba..a78516dc12f 100644 --- a/bfd/elf32-arc.c +++ b/bfd/elf32-arc.c @@ -1947,6 +1947,18 @@ elf_arc_relocate_section (bfd * output_bfd, return false; } + if (wrel != rel) + { + Elf_Internal_Shdr *rel_hdr; + size_t deleted = rel - wrel; + + rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); + rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; + rel_hdr = _bfd_elf_single_rel_hdr (input_section); + rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; + input_section->reloc_count -= deleted; + } + return true; } diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index b417cb0d67a..abe26e476ff 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -3600,14 +3600,6 @@ elf_i386_relocate_section (bfd *output_bfd, rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; - if (rel_hdr->sh_size == 0) - { - /* It is too late to remove an empty reloc section. Leave - one NONE reloc. - ??? What is wrong with an empty section??? */ - rel_hdr->sh_size = rel_hdr->sh_entsize; - deleted -= 1; - } rel_hdr = _bfd_elf_single_rel_hdr (input_section); rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; input_section->reloc_count -= deleted; diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index f17effdf176..3fd9f28cd52 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -9142,15 +9142,6 @@ ppc_elf_relocate_section (bfd *output_bfd, rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; - if (rel_hdr->sh_size == 0) - { - /* It is too late to remove an empty reloc section. Leave - one NONE reloc. - ??? What is wrong with an empty section??? */ - rel_hdr->sh_size = rel_hdr->sh_entsize; - deleted -= 1; - wrel++; - } relend = wrel; rel_hdr = _bfd_elf_single_rel_hdr (input_section); rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 00c1c32ffd2..e6c90a68b82 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -18082,14 +18082,6 @@ ppc64_elf_relocate_section (bfd *output_bfd, rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; - if (rel_hdr->sh_size == 0) - { - /* It is too late to remove an empty reloc section. Leave - one NONE reloc. - ??? What is wrong with an empty section??? */ - rel_hdr->sh_size = rel_hdr->sh_entsize; - deleted -= 1; - } rel_hdr = _bfd_elf_single_rel_hdr (input_section); rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; input_section->reloc_count -= deleted; diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index ebd2eb4299f..b6f97b5b69b 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -5099,14 +5099,6 @@ elf_x86_64_relocate_section (bfd *output_bfd, rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; - if (rel_hdr->sh_size == 0) - { - /* It is too late to remove an empty reloc section. Leave - one NONE reloc. - ??? What is wrong with an empty section??? */ - rel_hdr->sh_size = rel_hdr->sh_entsize; - deleted -= 1; - } rel_hdr = _bfd_elf_single_rel_hdr (input_section); rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; input_section->reloc_count -= deleted; diff --git a/ld/testsuite/ld-elf/linkonce1.d b/ld/testsuite/ld-elf/linkonce1.d index e4f9a70826f..654171dc7a6 100644 --- a/ld/testsuite/ld-elf/linkonce1.d +++ b/ld/testsuite/ld-elf/linkonce1.d @@ -2,11 +2,10 @@ #source: linkonce1b.s #ld: -r #objdump: -r +#xfail: [is_generic] .*: file format .* #... -RELOCATION RECORDS FOR \[.debug_frame\]: -OFFSET[ ]+TYPE[ ]+VALUE[ ]* -.*(NONE|unused|UNUSED).*\*ABS\* +RELOCATION RECORDS FOR \[.debug_frame\]: \(none\) #pass