[v2] LoongArch: Use more appropriate assertions for the relocation of TLS LE

Message ID 20250917022237.506797-1-cailulu@loongson.cn
State New
Headers
Series [v2] LoongArch: Use more appropriate assertions for the relocation of TLS LE |

Commit Message

Lulu Cai Sept. 17, 2025, 2:22 a.m. UTC
  PR ld/33427

Patches introduced in the GCC mainline:

commit 8cad8f94b450be9b73d07bdeef7fa1778d3f2b96
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Sep 5 15:40:51 2025 -0700

    c: Update TLS model after processing a TLS variable

    Set a tentative TLS model in grokvardecl and update TLS mode with
    the default TLS access model after a TLS variable has been fully
    processed if the default TLS access model is stronger,

triggered a linker error when building glibc using build-many-glibcs.py.

See: https://sourceware.org/pipermail/binutils/2025-September/144225.html

This fix uses more appropriate assertions.

---
Changes from v1:
  - Added the bug ID
---
 bfd/elfnn-loongarch.c                              |  2 +-
 ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 12 ++++++++++++
 ld/testsuite/ld-loongarch-elf/undefweak_le.s       |  7 +++++++
 3 files changed, 20 insertions(+), 1 deletion(-)
 create mode 100644 ld/testsuite/ld-loongarch-elf/undefweak_le.s
  

Comments

Xi Ruoyao Sept. 28, 2025, 3:49 a.m. UTC | #1
On Wed, 2025-09-17 at 10:22 +0800, Lulu Cai wrote:
> PR ld/33427
> 
> Patches introduced in the GCC mainline:
> 
> commit 8cad8f94b450be9b73d07bdeef7fa1778d3f2b96
> Author: H.J. Lu <hjl.tools@gmail.com>
> Date:   Fri Sep 5 15:40:51 2025 -0700
> 
>     c: Update TLS model after processing a TLS variable
> 
>     Set a tentative TLS model in grokvardecl and update TLS mode with
>     the default TLS access model after a TLS variable has been fully
>     processed if the default TLS access model is stronger,
> 
> triggered a linker error when building glibc using build-many-glibcs.py.
> 
> See: https://sourceware.org/pipermail/binutils/2025-September/144225.html
> 
> This fix uses more appropriate assertions.
> 
> ---
> Changes from v1:
>   - Added the bug ID
> ---
>  bfd/elfnn-loongarch.c                              |  2 +-
>  ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 12 ++++++++++++
>  ld/testsuite/ld-loongarch-elf/undefweak_le.s       |  7 +++++++
>  3 files changed, 20 insertions(+), 1 deletion(-)
>  create mode 100644 ld/testsuite/ld-loongarch-elf/undefweak_le.s
> 
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index 8beb3d84079..d10f9f6bd0f 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -4401,7 +4401,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
>  	case R_LARCH_TLS_LE_LO12_R:
>  	case R_LARCH_TLS_LE64_LO20:
>  	case R_LARCH_TLS_LE64_HI12:
> -	  BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
> +	  BFD_ASSERT (bfd_link_executable (info));
>  
>  	  relocation += rel->r_addend;
>  	  relocation = tlsoff (info, relocation);
> diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> index a33727f2efd..5bc48b28ca8 100644
> --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> @@ -172,6 +172,18 @@ if [istarget "loongarch64-*-*"] {
>  	  "desc-ie-norelax" \
>        ] \
>    ] \
> +
> +  run_ld_link_tests \
> +      [list \
> +	   [list \
> +		"undefind weak with tls le" \
> +		"" "-e0" \
> +		"" \
> +		{undefweak_le.s} \
> +		{} \
> +		"undefweak_le" \
> +	   ] \
> +      ]
>  }
>  
>  if [istarget "loongarch64-*-*"] {
> diff --git a/ld/testsuite/ld-loongarch-elf/undefweak_le.s b/ld/testsuite/ld-loongarch-elf/undefweak_le.s
> new file mode 100644
> index 00000000000..6e730182448
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/undefweak_le.s
> @@ -0,0 +1,7 @@
> +_start:
> +	lu12i.w	$t0,%le_hi20_r(undefweak_le)
> +	add.d	$t0,$t0,$tp,%le_add_r(undefweak_le)
> +	ld.d	$t0,$t0,%le_lo12_r(undefweak_le)
> +
> +	.weak	undefweak_le
> +	.hidden	undefweak_le

Well, the test case:

extern __thread int x [[gnu::weak]];
int main() {__builtin_printf("%p\n", &x);}

seems not working on both loongarch64 and x86_64 even before the GCC and
Binutils change.  On loongarch64 it triggers a segfault in Glibc
_dl_relocate_object_no_relro, on x86_64 the output is something like
0x7fc1f8299740 instead of (nil) that people expect for a undefweak
symbol.

Should the issue be fixed or should we just consider undefweak thread-
local symbols invalid?
  
Lulu Cai Sept. 29, 2025, 6:35 a.m. UTC | #2
On 9/28/25 11:49 AM, Xi Ruoyao wrote:
> On Wed, 2025-09-17 at 10:22 +0800, Lulu Cai wrote:
>> PR ld/33427
>>
>> Patches introduced in the GCC mainline:
>>
>> commit 8cad8f94b450be9b73d07bdeef7fa1778d3f2b96
>> Author: H.J. Lu <hjl.tools@gmail.com>
>> Date:   Fri Sep 5 15:40:51 2025 -0700
>>
>>      c: Update TLS model after processing a TLS variable
>>
>>      Set a tentative TLS model in grokvardecl and update TLS mode with
>>      the default TLS access model after a TLS variable has been fully
>>      processed if the default TLS access model is stronger,
>>
>> triggered a linker error when building glibc using build-many-glibcs.py.
>>
>> See: https://sourceware.org/pipermail/binutils/2025-September/144225.html
>>
>> This fix uses more appropriate assertions.
>>
>> ---
>> Changes from v1:
>>    - Added the bug ID
>> ---
>>   bfd/elfnn-loongarch.c                              |  2 +-
>>   ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 12 ++++++++++++
>>   ld/testsuite/ld-loongarch-elf/undefweak_le.s       |  7 +++++++
>>   3 files changed, 20 insertions(+), 1 deletion(-)
>>   create mode 100644 ld/testsuite/ld-loongarch-elf/undefweak_le.s
>>
>> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
>> index 8beb3d84079..d10f9f6bd0f 100644
>> --- a/bfd/elfnn-loongarch.c
>> +++ b/bfd/elfnn-loongarch.c
>> @@ -4401,7 +4401,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
>>   	case R_LARCH_TLS_LE_LO12_R:
>>   	case R_LARCH_TLS_LE64_LO20:
>>   	case R_LARCH_TLS_LE64_HI12:
>> -	  BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
>> +	  BFD_ASSERT (bfd_link_executable (info));
>>   
>>   	  relocation += rel->r_addend;
>>   	  relocation = tlsoff (info, relocation);
>> diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
>> index a33727f2efd..5bc48b28ca8 100644
>> --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
>> +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
>> @@ -172,6 +172,18 @@ if [istarget "loongarch64-*-*"] {
>>   	  "desc-ie-norelax" \
>>         ] \
>>     ] \
>> +
>> +  run_ld_link_tests \
>> +      [list \
>> +	   [list \
>> +		"undefind weak with tls le" \
>> +		"" "-e0" \
>> +		"" \
>> +		{undefweak_le.s} \
>> +		{} \
>> +		"undefweak_le" \
>> +	   ] \
>> +      ]
>>   }
>>   
>>   if [istarget "loongarch64-*-*"] {
>> diff --git a/ld/testsuite/ld-loongarch-elf/undefweak_le.s b/ld/testsuite/ld-loongarch-elf/undefweak_le.s
>> new file mode 100644
>> index 00000000000..6e730182448
>> --- /dev/null
>> +++ b/ld/testsuite/ld-loongarch-elf/undefweak_le.s
>> @@ -0,0 +1,7 @@
>> +_start:
>> +	lu12i.w	$t0,%le_hi20_r(undefweak_le)
>> +	add.d	$t0,$t0,$tp,%le_add_r(undefweak_le)
>> +	ld.d	$t0,$t0,%le_lo12_r(undefweak_le)
>> +
>> +	.weak	undefweak_le
>> +	.hidden	undefweak_le
> Well, the test case:
>
> extern __thread int x [[gnu::weak]];
> int main() {__builtin_printf("%p\n", &x);}
>
> seems not working on both loongarch64 and x86_64 even before the GCC and
> Binutils change.  On loongarch64 it triggers a segfault in Glibc
> _dl_relocate_object_no_relro, on x86_64 the output is something like
> 0x7fc1f8299740 instead of (nil) that people expect for a undefweak
> symbol.
>
> Should the issue be fixed or should we just consider undefweak thread-
> local symbols invalid?
>
We think this might need to be fixed; at least, it shouldn’t directly 
trigger a segfault. We might handle this matter later.
  

Patch

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 8beb3d84079..d10f9f6bd0f 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -4401,7 +4401,7 @@  loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	case R_LARCH_TLS_LE_LO12_R:
 	case R_LARCH_TLS_LE64_LO20:
 	case R_LARCH_TLS_LE64_HI12:
-	  BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
+	  BFD_ASSERT (bfd_link_executable (info));
 
 	  relocation += rel->r_addend;
 	  relocation = tlsoff (info, relocation);
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index a33727f2efd..5bc48b28ca8 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -172,6 +172,18 @@  if [istarget "loongarch64-*-*"] {
 	  "desc-ie-norelax" \
       ] \
   ] \
+
+  run_ld_link_tests \
+      [list \
+	   [list \
+		"undefind weak with tls le" \
+		"" "-e0" \
+		"" \
+		{undefweak_le.s} \
+		{} \
+		"undefweak_le" \
+	   ] \
+      ]
 }
 
 if [istarget "loongarch64-*-*"] {
diff --git a/ld/testsuite/ld-loongarch-elf/undefweak_le.s b/ld/testsuite/ld-loongarch-elf/undefweak_le.s
new file mode 100644
index 00000000000..6e730182448
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/undefweak_le.s
@@ -0,0 +1,7 @@ 
+_start:
+	lu12i.w	$t0,%le_hi20_r(undefweak_le)
+	add.d	$t0,$t0,$tp,%le_add_r(undefweak_le)
+	ld.d	$t0,$t0,%le_lo12_r(undefweak_le)
+
+	.weak	undefweak_le
+	.hidden	undefweak_le