From bc5451c19e226b77aa69e4f7e29a43516335dedf Mon Sep 17 00:00:00 2001 From: Tsiry Sandratraina Date: Sat, 8 Aug 2026 02:02:10 +0300 Subject: [PATCH] bindings: place .tdata in the PT_TLS segment explicitly The linker scripts assigned .tdata to a PT_LOAD segment and only .tbss to PT_TLS. GNU ld includes every SHF_TLS section in PT_TLS regardless of the explicit assignment, so the segment spanned .tdata..tbss as tls.c expects and this went unnoticed. LLD honours the assignment as written, leaving PT_TLS starting at .tbss -- a page above .tdata, since .tdata is padded to MAXPAGESIZE. Initialised __thread variables then get a TP offset of -(MAXPAGESIZE - 16). That is representable on x86_64, where variant II TLS puts variables below the thread pointer anyway, but not on aarch64, where linking test_tls fails with: relocation R_AARCH64_TLSLE_ADD_TPREL_HI12 out of range: ... references '_data_not_bss' Naming :tbss on .tdata as well reproduces what GNU ld already emitted, so this is a no-op there, and gives LLD the same layout: PT_TLS covering .tdata (padded) followed by .tbss, matching _ltdata/_ltbss and the block that solo5_tls_init() copies. --- bindings/solo5_hvt.lds | 2 +- bindings/solo5_muen.lds | 2 +- bindings/solo5_spt.lds | 2 +- bindings/solo5_stub.lds | 2 +- bindings/solo5_virtio.lds | 2 +- bindings/solo5_xen.lds | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bindings/solo5_hvt.lds b/bindings/solo5_hvt.lds index d5d0cb9..3c862c8 100644 --- a/bindings/solo5_hvt.lds +++ b/bindings/solo5_hvt.lds @@ -127,7 +127,7 @@ SECTIONS { _stdata = .; *(.tdata) . = ALIGN(CONSTANT(MAXPAGESIZE)); - } :tdata + } :tdata :tbss /* * _edata is the address of the end of the area to be copied with multiboot diff --git a/bindings/solo5_muen.lds b/bindings/solo5_muen.lds index 0b7fc40..6f885f0 100644 --- a/bindings/solo5_muen.lds +++ b/bindings/solo5_muen.lds @@ -126,7 +126,7 @@ SECTIONS { _stdata = .; *(.tdata) . = ALIGN(CONSTANT(MAXPAGESIZE)); - } :tdata + } :tdata :tbss /* * _edata is the address of the end of the area to be copied with multiboot diff --git a/bindings/solo5_spt.lds b/bindings/solo5_spt.lds index 4b4172b..dffa311 100644 --- a/bindings/solo5_spt.lds +++ b/bindings/solo5_spt.lds @@ -125,7 +125,7 @@ SECTIONS { _stdata = .; *(.tdata) . = ALIGN(CONSTANT(MAXPAGESIZE)); - } :tdata + } :tdata :tbss /* * _edata is the address of the end of the area to be copied with multiboot diff --git a/bindings/solo5_stub.lds b/bindings/solo5_stub.lds index 2b3d90a..b59fae5 100644 --- a/bindings/solo5_stub.lds +++ b/bindings/solo5_stub.lds @@ -125,7 +125,7 @@ SECTIONS { _stdata = .; *(.tdata) . = ALIGN(CONSTANT(MAXPAGESIZE)); - } :tdata + } :tdata :tbss /* * _edata is the address of the end of the area to be copied with multiboot diff --git a/bindings/solo5_virtio.lds b/bindings/solo5_virtio.lds index e1eb4b8..ddfcecd 100644 --- a/bindings/solo5_virtio.lds +++ b/bindings/solo5_virtio.lds @@ -126,7 +126,7 @@ SECTIONS { _stdata = .; *(.tdata) . = ALIGN(CONSTANT(MAXPAGESIZE)); - } :tdata + } :tdata :tbss /* * _edata is the address of the end of the area to be copied with multiboot diff --git a/bindings/solo5_xen.lds b/bindings/solo5_xen.lds index 079c74f..b3599b1 100644 --- a/bindings/solo5_xen.lds +++ b/bindings/solo5_xen.lds @@ -131,7 +131,7 @@ SECTIONS { _stdata = .; *(.tdata) . = ALIGN(CONSTANT(MAXPAGESIZE)); - } :tdata + } :tdata :tbss /* * _edata is the address of the end of the area to be copied with multiboot -- 2.51.2