[PATCH v3] elf: Don't set sh_offset of .tbss sections beyond EOF
H.J. Lu
hjl.tools@gmail.com
Tue Apr 29 21:38:00 GMT 2025
If there is no .tdata section, put meaningless sh_offset of .tbss sections
without file contents somewhere within the first page, in an attempt to
not point past EOF and avoid sh_offset of zero.
bfd/
PR ld/32896
* elf.c (IS_TDATA): New.
(make_mapping): Set has_tdata if there is .tdata section.
(assign_file_positions_for_load_sections): Don't set sh_offset
of .tbss sections beyond EOF if there is no .tdata section.
(rewrite_elf_program_header): Set has_tdata if there is .tdata
section.
(copy_elf_program_header): Likewise.
include/
PR ld/32896
* elf/internal.h (elf_segment_map): Add has_tdata.
ld/
PR ld/32896
* testsuite/ld-elf/tbss4.d: Updated.
* testsuite/ld-elf/tbss5.d: New file.
* testsuite/ld-elf/tbss5.s: Likewise.
* testsuite/ld-elf/tbss6.d: Likewise.
* testsuite/ld-elf/tbss6.s: Likewise.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
bfd/elf.c | 26 ++++++++++++++++++++++++--
include/elf/internal.h | 2 ++
ld/testsuite/ld-elf/tbss4.d | 2 +-
ld/testsuite/ld-elf/tbss5.d | 9 +++++++++
ld/testsuite/ld-elf/tbss5.s | 14 ++++++++++++++
ld/testsuite/ld-elf/tbss6.d | 12 ++++++++++++
ld/testsuite/ld-elf/tbss6.s | 21 +++++++++++++++++++++
7 files changed, 83 insertions(+), 3 deletions(-)
create mode 100644 ld/testsuite/ld-elf/tbss5.d
create mode 100644 ld/testsuite/ld-elf/tbss5.s
create mode 100644 ld/testsuite/ld-elf/tbss6.d
create mode 100644 ld/testsuite/ld-elf/tbss6.s
diff --git a/bfd/elf.c b/bfd/elf.c
index b6f50701928..d53f252d3ca 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4875,6 +4875,10 @@ _bfd_elf_find_segment_containing_section (bfd * abfd, asection * section)
return NULL;
}
+#define IS_TDATA(s) \
+ (((s)->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) \
+ == (SEC_THREAD_LOCAL | SEC_LOAD))
+
/* Create a mapping from a set of sections to a program segment. */
static struct elf_segment_map *
@@ -4897,7 +4901,11 @@ make_mapping (bfd *abfd,
m->next = NULL;
m->p_type = PT_LOAD;
for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++)
- m->sections[i - from] = *hdrpp;
+ {
+ m->sections[i - from] = *hdrpp;
+ if (IS_TDATA (*hdrpp))
+ m->has_tdata = 1;
+ }
m->count = to - from;
if (from == 0 && phdr)
@@ -6306,7 +6314,15 @@ assign_file_positions_for_load_sections (bfd *abfd,
p_offset % p_align == p_vaddr % p_align. */
bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr,
off, align);
- this_hdr->sh_offset = sec->filepos = off + adjust;
+ file_ptr aligned_off = off + adjust;
+ /* If there is no .tdata section, put meaningless
+ sh_offset of .tbss sections without file contents
+ somewhere within the first page, in an attempt to
+ not point past EOF and avoid sh_offset of zero. */
+ if (!m->has_tdata
+ && aligned_off >= (file_ptr) maxpagesize)
+ aligned_off = (aligned_off + align - 1) % align + 1;
+ this_hdr->sh_offset = sec->filepos = aligned_off;
}
else if (p->p_type == PT_LOAD)
{
@@ -7721,6 +7737,9 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd, bfd_vma maxpagesize)
{
if (INCLUDE_SECTION_IN_SEGMENT (section, segment, opb, p_paddr_valid))
{
+ if (IS_TDATA (section))
+ map->has_tdata = 1;
+
output_section = section->output_section;
sections[j++] = section;
@@ -8158,6 +8177,9 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
this_hdr = &(elf_section_data(section)->this_hdr);
if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
{
+ if (IS_TDATA (section))
+ map->has_tdata = 1;
+
map->sections[isec++] = section->output_section;
if ((section->flags & SEC_ALLOC) != 0)
{
diff --git a/include/elf/internal.h b/include/elf/internal.h
index 9c546741ad8..54add8fe49a 100644
--- a/include/elf/internal.h
+++ b/include/elf/internal.h
@@ -296,6 +296,8 @@ struct elf_segment_map
flag set are placed after one with includes_filehdr set, and
before PT_LOAD headers without this flag set. */
unsigned int no_sort_lma : 1;
+ /* Whether this segment has .tdata section. */
+ unsigned int has_tdata : 1;
/* Index holding original order before sorting segments. */
unsigned int idx;
/* Number of sections (may be 0). */
diff --git a/ld/testsuite/ld-elf/tbss4.d b/ld/testsuite/ld-elf/tbss4.d
index 77a865b5e1a..fabc2d57b41 100644
--- a/ld/testsuite/ld-elf/tbss4.d
+++ b/ld/testsuite/ld-elf/tbss4.d
@@ -3,7 +3,7 @@
#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu*
#...
- +TLS +0x0+1014 .*
+ +TLS +0x0+4 .*
#...
.* \.tbss
#pass
diff --git a/ld/testsuite/ld-elf/tbss5.d b/ld/testsuite/ld-elf/tbss5.d
new file mode 100644
index 00000000000..a935091fc5e
--- /dev/null
+++ b/ld/testsuite/ld-elf/tbss5.d
@@ -0,0 +1,9 @@
+#ld: -e _start --rosegment -z separate-code -z max-page-size=0x10000 -z common-page-size=0x10000
+#readelf: -l --wide
+#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu*
+
+#...
+ +TLS +0x0+400 .*
+#...
+.* \.tbss
+#pass
diff --git a/ld/testsuite/ld-elf/tbss5.s b/ld/testsuite/ld-elf/tbss5.s
new file mode 100644
index 00000000000..c172e243df1
--- /dev/null
+++ b/ld/testsuite/ld-elf/tbss5.s
@@ -0,0 +1,14 @@
+ .section .gcc_except_table,"aw",%progbits
+ .p2align 4
+ .ascii "Odd number of chars"
+
+ .section .tbss,"awT",%nobits
+ .p2align 10
+ .type abc, %object
+ .size abc, 4
+abc:
+ .zero 4
+
+ .text
+ .global _start
+_start:
diff --git a/ld/testsuite/ld-elf/tbss6.d b/ld/testsuite/ld-elf/tbss6.d
new file mode 100644
index 00000000000..457f64b42a4
--- /dev/null
+++ b/ld/testsuite/ld-elf/tbss6.d
@@ -0,0 +1,12 @@
+#ld: -e _start --rosegment -z separate-code -z max-page-size=0x10000 -z common-page-size=0x10000
+#readelf: -S -l --wide
+#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu*
+
+#...
+ \[ [0-9]+\] \.tdata +PROGBITS +0+4[0-9]+0400 010400 0+4 00 WAT +0 +0 1024
+ \[ [0-9]+\] \.tbss +NOBITS +0+4[0-9]+0800 010800 0+4 00 WAT +0 +0 1024
+#...
+ +TLS +0x0+10400 .*
+#...
+.* \.tdata \.tbss
+#pass
diff --git a/ld/testsuite/ld-elf/tbss6.s b/ld/testsuite/ld-elf/tbss6.s
new file mode 100644
index 00000000000..8750038f226
--- /dev/null
+++ b/ld/testsuite/ld-elf/tbss6.s
@@ -0,0 +1,21 @@
+ .section .gcc_except_table,"aw",@progbits
+ .p2align 4
+ .ascii "Odd number of chars"
+
+ .section .tbss,"awT",%nobits
+ .p2align 10
+ .type abc, %object
+ .size abc, 4
+abc:
+ .zero 4
+
+ .section .tdata,"awT",%progbits
+ .p2align 10
+ .type foo, %object
+ .size foo, 4
+foo:
+ .zero 4
+
+ .text
+ .global _start
+_start:
--
2.49.0
More information about the Binutils
mailing list