[PATCH 3/4] s390: Do not emit orphaned GOT entry for TLS IE to LE transition

Jens Remus jremus@linux.ibm.com
Thu Nov 13 13:21:11 GMT 2025


Commit 69fc87f180bf introduced TLS support for s390 32-bit and 64-bit.
It defined GOT_TLS_IE_NLT in both elf32-s390.c and elf64-s390.c, but
erroneously assigned it the same value as GOT_TLS_IE in elf64-s390.c.
As a consequence the linker for s390 64-bit erroneously emitted an
orphaned GOT entry when performing TLS Initial Exec (IE) to Local
Exec (LE) transition optimization.

Correct the value of GOT_TLS_IE_NLT in elf64-s390.c.  This causes the
liker to actually optimize away the GOT entry when performing IE to LE
transition.  While at it add a comment that the suffix NLT denotes
"no literal (pool entry)".

Found while inspecting and cleaning up differences between elf32-s390.c
and elf64-s390.c.

bfd/
	* elf32-s390.c (GOT_TLS_IE_NLT): Add comment that NLT denotes
	no literal pool entry.
	* elf64-s390.c (GOT_TLS_IE_NLT): Likewise.  Correct value.

ld/testsuite/
	* ld-s390/tlsbin_64.dd: Adjust expected test results.
	* ld-s390/tlsbin_64.sd: Likewise.

Fixes: 69fc87f180bf
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---
 bfd/elf32-s390.c                  |  2 +-
 bfd/elf64-s390.c                  |  2 +-
 ld/testsuite/ld-s390/tlsbin_64.dd | 16 ++++++++--------
 ld/testsuite/ld-s390/tlsbin_64.sd |  4 +---
 4 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
index 52aad070d441..ea5368ea9ddb 100644
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -661,7 +661,7 @@ struct elf_s390_link_hash_entry
 #define GOT_NORMAL	1
 #define GOT_TLS_GD	2
 #define GOT_TLS_IE	3
-#define GOT_TLS_IE_NLT	4
+#define GOT_TLS_IE_NLT	4	/* Initial Exec, no literal pool entry.  */
   unsigned char tls_type;
 
   /* For pointer equality reasons we might need to change the symbol
diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
index f5a80e73f113..9242407b1b5d 100644
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -653,7 +653,7 @@ struct elf_s390_link_hash_entry
 #define GOT_NORMAL	1
 #define GOT_TLS_GD	2
 #define GOT_TLS_IE	3
-#define GOT_TLS_IE_NLT	3
+#define GOT_TLS_IE_NLT	4	/* Initial Exec, no literal pool entry.  */
   unsigned char tls_type;
 
   /* For pointer equality reasons we might need to change the symbol
diff --git a/ld/testsuite/ld-s390/tlsbin_64.dd b/ld/testsuite/ld-s390/tlsbin_64.dd
index d2aa851af46a..124c268b5646 100644
--- a/ld/testsuite/ld-s390/tlsbin_64.dd
+++ b/ld/testsuite/ld-s390/tlsbin_64.dd
@@ -24,10 +24,10 @@ Disassembly of section .text:
  +[0-9a-f]+:	a7 d5 00 3e       	bras	%r13,[0-9a-f]+ <fn2\+0x82>
 # sG1@tlsgd
  +[0-9a-f]+:	00 00 00 00       	.long	0x00000000
- +[0-9a-f]+:	00 00 00 60       	.long	0x00000060
+ +[0-9a-f]+:	00 00 00 50       	.long	0x00000050
 # sG2@tlsgd
  +[0-9a-f]+:	00 00 00 00       	.long	0x00000000
- +[0-9a-f]+:	00 00 00 48       	.long	0x00000048
+ +[0-9a-f]+:	00 00 00 40       	.long	0x00000040
 # sg1@tlsgd
  +[0-9a-f]+:	ff ff ff ff       	.long	0xffffffff
  +[0-9a-f]+:	ff ff ff 60       	.long	0xffffff60
@@ -57,7 +57,7 @@ Disassembly of section .text:
  +[0-9a-f]+:	ff ff ff a4       	.long	0xffffffa4
 # sG2@gotntpoff
  +[0-9a-f]+:	00 00 00 00       	.long	0x00000000
- +[0-9a-f]+:	00 00 00 48       	.long	0x00000048
+ +[0-9a-f]+:	00 00 00 40       	.long	0x00000040
 # sg1@gotntpoff
  +[0-9a-f]+:	ff ff ff ff       	.long	0xffffffff
  +[0-9a-f]+:	ff ff ff 60       	.long	0xffffff60
@@ -133,7 +133,7 @@ Disassembly of section .text:
  +[0-9a-f]+:	e3 33 c0 00 00 04 	lg	%r3,0\(%r3,%r12\)
  +[0-9a-f]+:	41 33 90 00       	la	%r3,0\(%r3,%r9\)
 # IE against global var defined in exec with larl got access
- +[0-9a-f]+:	c0 30 [0-9a-f ]+ 	larl	%r3,[0-9a-f]+ <_GLOBAL_OFFSET_TABLE_\+0x38>
+ +[0-9a-f]+:	c0 30 [0-9a-f ]+ 	larl	%r3,[0-9a-f]+ <_GLOBAL_OFFSET_TABLE_\+0x30>
  +[0-9a-f]+:	eb 43 00 00 00 0d 	sllg	%r4,%r3,0
  +[0-9a-f]+:	41 54 90 00       	la	%r5,0\(%r4,%r9\)
 # IE against local var with larl got access
@@ -141,7 +141,7 @@ Disassembly of section .text:
  +[0-9a-f]+:	eb 43 00 00 00 0d 	sllg	%r4,%r3,0
  +[0-9a-f]+:	41 54 90 00       	la	%r5,0\(%r4,%r9\)
 # IE against hidden var with larl got access
- +[0-9a-f]+:	c0 30 [0-9a-f ]+ 	larl	%r3,[0-9a-f]+ <_GLOBAL_OFFSET_TABLE_\+0x40>
+ +[0-9a-f]+:	c0 30 [0-9a-f ]+ 	larl	%r3,[0-9a-f]+ <_GLOBAL_OFFSET_TABLE_\+0x38>
  +[0-9a-f]+:	eb 43 00 00 00 0d 	sllg	%r4,%r3,0
  +[0-9a-f]+:	41 54 90 00       	la	%r5,0\(%r4,%r9\)
 # IE against global var with small got access (no optimization)
@@ -149,13 +149,13 @@ Disassembly of section .text:
  +[0-9a-f]+:	41 33 90 00       	la	%r3,0\(%r3,%r9\)
 # IE against global var defined in exec with small got access
 # (no optimization)
- +[0-9a-f]+:	e3 30 c0 38 00 04 	lg	%r3,56\(%r12\)
+ +[0-9a-f]+:	e3 30 c0 30 00 04 	lg	%r3,48\(%r12\)
  +[0-9a-f]+:	41 33 90 00       	la	%r3,0\(%r3,%r9\)
 # IE against local var with small got access (no optimization)
  +[0-9a-f]+:	e3 30 c0 20 00 04 	lg	%r3,32\(%r12\)
  +[0-9a-f]+:	41 33 90 00       	la	%r3,0\(%r3,%r9\)
 # IE against hidden var with small got access (no optimization)
- +[0-9a-f]+:	e3 30 c0 40 00 04 	lg	%r3,64\(%r12\)
+ +[0-9a-f]+:	e3 30 c0 38 00 04 	lg	%r3,56\(%r12\)
  +[0-9a-f]+:	41 33 90 00       	la	%r3,0\(%r3,%r9\)
 # function epilog
  +[0-9a-f]+:	eb 6e f0 d0 00 04 	lmg	%r6,%r14,208\(%r15\)
@@ -177,7 +177,7 @@ Disassembly of section .text:
  +[0-9a-f]+:	a7 d5 00 16       	bras	%r13,[0-9a-f]+ <_start\+0x30>
 # sG6@indntpoff
  +[0-9a-f]+:	00 00 00 00       	.long	0x00000000
- +[0-9a-f]+:	01 00 18 18       	.long	0x01001818
+ +[0-9a-f]+:	01 00 18 08       	.long	0x01001808
 # bg6@indntpoff
  +[0-9a-f]+:	ff ff ff ff       	.long	0xffffffff
  +[0-9a-f]+:	ff ff ff d4       	.long	0xffffffd4
diff --git a/ld/testsuite/ld-s390/tlsbin_64.sd b/ld/testsuite/ld-s390/tlsbin_64.sd
index 6618e455d731..d4309231557a 100644
--- a/ld/testsuite/ld-s390/tlsbin_64.sd
+++ b/ld/testsuite/ld-s390/tlsbin_64.sd
@@ -11,8 +11,6 @@ Contents of section .got:
  [0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00000000 00000000  .*
  [0-9a-f]+ 00000000 00000000 [0-9a-f]+ [0-9a-f]+  .*
  [0-9a-f]+ ffffffff ffffff88 00000000 00000000  .*
- [0-9a-f]+ 00000000 00000000 ffffffff ffffff68  .*
- [0-9a-f]+ ffffffff ffffffa8 00000000 00000000  .*
- [0-9a-f]+ 00000000 00000000 00000000 00000000  .*
+ [0-9a-f]+ ffffffff ffffff68 ffffffff ffffffa8  .*
  [0-9a-f]+ 00000000 00000000 00000000 00000000  .*
  [0-9a-f]+ 00000000 00000000                    .*
-- 
2.48.1



More information about the Binutils mailing list