[binutils-gdb] RELOC_AGAINST_DISCARDED_SECTION zero size reloc sections
Alan Modra
amodra@sourceware.org
Fri Jul 18 23:05:02 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=129cdfc16433bd755c81357bb2f665ca93edb0b4
commit 129cdfc16433bd755c81357bb2f665ca93edb0b4
Author: Alan Modra <amodra@gmail.com>
Date: Fri Jul 18 09:26:10 2025 +0930
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:
---
bfd/elf-bfd.h | 27 +++++++++++----------------
bfd/elf32-arc.c | 12 ++++++++++++
bfd/elf32-i386.c | 8 --------
bfd/elf32-ppc.c | 9 ---------
bfd/elf64-ppc.c | 8 --------
bfd/elf64-x86-64.c | 8 --------
ld/testsuite/ld-elf/linkonce1.d | 5 ++---
7 files changed, 25 insertions(+), 52 deletions(-)
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
More information about the Binutils-cvs
mailing list