S390: Enable static PIE

Message ID 20220428141530.567838-1-stli@linux.ibm.com
State Committed
Headers
Series S390: Enable static PIE |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent
dj/TryBot-32bit success Build for i686

Commit Message

Stefan Liebler April 28, 2022, 2:15 p.m. UTC
  This commit enables static PIE on 64bit.  On 31bit, static PIE is
not supported.

A new configure check in sysdeps/s390/s390-64/configure.ac also performs
a minimal test for requirements in ld:
Ensure you also have those patches for:
- binutils (ld)
  - "[PR ld/22263] s390: Avoid dynamic TLS relocs in PIE"
    https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=26b1426577b5dcb32d149c64cca3e603b81948a9
    (Tested by configure check above)
    Otherwise there will be a R_390_TLS_TPOFF relocation, which fails to
    be processed in _dl_relocate_static_pie() as static TLS map is not setup.
  - "s390: Add DT_JMPREL pointing to .rela.[i]plt with static-pie"
    https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d942d8db12adf4c9e5c7d9ed6496a779ece7149e
    (We can't test it in configure as we are not able to link a static PIE
    executable if the system glibc lacks static PIE support)
    Otherwise there won't be DT_JMPREL, DT_PLTRELA, DT_PLTRELASZ entries
    and the IFUNC symbols are not processed, which leads to crashes.

- kernel (the mentioned links to the commits belong to 5.19 merge window):
  - "s390/mmap: increase stack/mmap gap to 128MB"
    https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2
  - "s390/vdso: move vdso mapping to its own function"
    https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8
  - "s390/vdso: map vdso above stack"
    https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033
  - "s390/vdso: add vdso randomization"
    https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25
  (We can't test the kernel of the target system)
  Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0),
  static PIE executables like ldconfig will crash.  While startup sbrk is
  used to enlarge the HEAP.  Unfortunately the underlying brk syscall fails
  as there is not enough space after the HEAP.  Then the address of the TLS
  image is invalid and the following memcpy in __libc_setup_tls() leads
  to a segfault.
  If /proc/sys/kernel/randomize_va_space is activated (default: 2), there
  is enough space after HEAP.

This commit also adjusts startup code in start.S to be ready for static PIE.
We have to add a wrapper function for main as we are not allowed to use
GOT relocations before __libc_start_main is called.
(Compare also to:
- commit 14d886edbd3d80b771e1c42fbd9217f9074de9c6
  "aarch64: fix start code for static pie"
- commit 3d1d79283e6de4f7c434cb67fb53a4fd28359669
  "aarch64: fix static pie enabled libc when main is in a shared library"
)
---
 sysdeps/s390/s390-64/configure    | 104 ++++++++++++++++++++++++++++++
 sysdeps/s390/s390-64/configure.ac |  74 +++++++++++++++++++++
 sysdeps/s390/s390-64/start.S      |  28 ++++++++
 3 files changed, 206 insertions(+)
 create mode 100644 sysdeps/s390/s390-64/configure
 create mode 100644 sysdeps/s390/s390-64/configure.ac
  

Comments

Florian Weimer May 2, 2022, 9:13 a.m. UTC | #1
* Stefan Liebler via Libc-alpha:

> This commit enables static PIE on 64bit.  On 31bit, static PIE is
> not supported.
>
> - kernel (the mentioned links to the commits belong to 5.19 merge window):
>   - "s390/mmap: increase stack/mmap gap to 128MB"
>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2
>   - "s390/vdso: move vdso mapping to its own function"
>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8
>   - "s390/vdso: map vdso above stack"
>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033
>   - "s390/vdso: add vdso randomization"
>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25
>   (We can't test the kernel of the target system)
>   Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0),
>   static PIE executables like ldconfig will crash.  While startup sbrk is
>   used to enlarge the HEAP.  Unfortunately the underlying brk syscall fails
>   as there is not enough space after the HEAP.  Then the address of the TLS
>   image is invalid and the following memcpy in __libc_setup_tls() leads
>   to a segfault.
>   If /proc/sys/kernel/randomize_va_space is activated (default: 2), there
>   is enough space after HEAP.

I'll work an early allocator that does not use the TCB and which should
avoid the sbrk crash.  Will that be sufficient to enable static PIE
binaries to run on unchanged kernels?

Otherwise I fear that we end up in a world of pain if we turn ldconfig
into a static PIE binary. 8-(

Thanks,
Florian
  
Adhemerval Zanella May 2, 2022, 3:38 p.m. UTC | #2
On 02/05/2022 06:13, Florian Weimer via Libc-alpha wrote:
> * Stefan Liebler via Libc-alpha:
> 
>> This commit enables static PIE on 64bit.  On 31bit, static PIE is
>> not supported.
>>
>> - kernel (the mentioned links to the commits belong to 5.19 merge window):
>>   - "s390/mmap: increase stack/mmap gap to 128MB"
>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2
>>   - "s390/vdso: move vdso mapping to its own function"
>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8
>>   - "s390/vdso: map vdso above stack"
>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033
>>   - "s390/vdso: add vdso randomization"
>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25
>>   (We can't test the kernel of the target system)
>>   Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0),
>>   static PIE executables like ldconfig will crash.  While startup sbrk is
>>   used to enlarge the HEAP.  Unfortunately the underlying brk syscall fails
>>   as there is not enough space after the HEAP.  Then the address of the TLS
>>   image is invalid and the following memcpy in __libc_setup_tls() leads
>>   to a segfault.
>>   If /proc/sys/kernel/randomize_va_space is activated (default: 2), there
>>   is enough space after HEAP.
> 
> I'll work an early allocator that does not use the TCB and which should
> avoid the sbrk crash.  Will that be sufficient to enable static PIE
> binaries to run on unchanged kernels?
> 
> Otherwise I fear that we end up in a world of pain if we turn ldconfig
> into a static PIE binary. 8-(


I agree that ideally it should not rely a patched kernel to overcome the
glibc issue of handling sbrk call failures and having a working loader
allocator that work regardless of kernel version is the best approach. 

As I put on weekly call, I would prefer to make it only use mmap as
for simplicity.
  
Florian Weimer May 2, 2022, 7:18 p.m. UTC | #3
* Adhemerval Zanella:

> On 02/05/2022 06:13, Florian Weimer via Libc-alpha wrote:
>> * Stefan Liebler via Libc-alpha:
>> 
>>> This commit enables static PIE on 64bit.  On 31bit, static PIE is
>>> not supported.
>>>
>>> - kernel (the mentioned links to the commits belong to 5.19 merge window):
>>>   - "s390/mmap: increase stack/mmap gap to 128MB"
>>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2
>>>   - "s390/vdso: move vdso mapping to its own function"
>>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8
>>>   - "s390/vdso: map vdso above stack"
>>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033
>>>   - "s390/vdso: add vdso randomization"
>>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25
>>>   (We can't test the kernel of the target system)
>>>   Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0),
>>>   static PIE executables like ldconfig will crash.  While startup sbrk is
>>>   used to enlarge the HEAP.  Unfortunately the underlying brk syscall fails
>>>   as there is not enough space after the HEAP.  Then the address of the TLS
>>>   image is invalid and the following memcpy in __libc_setup_tls() leads
>>>   to a segfault.
>>>   If /proc/sys/kernel/randomize_va_space is activated (default: 2), there
>>>   is enough space after HEAP.
>> 
>> I'll work an early allocator that does not use the TCB and which should
>> avoid the sbrk crash.  Will that be sufficient to enable static PIE
>> binaries to run on unchanged kernels?
>> 
>> Otherwise I fear that we end up in a world of pain if we turn ldconfig
>> into a static PIE binary. 8-(
>
>
> I agree that ideally it should not rely a patched kernel to overcome the
> glibc issue of handling sbrk call failures and having a working loader
> allocator that work regardless of kernel version is the best approach. 
>
> As I put on weekly call, I would prefer to make it only use mmap as
> for simplicity. 

Getting mmap to work is actually the hard part due to six-argument
system call.  Trying sbrk first does not add much complexity.  I posted
my series:

  Linux: Fall back to mmap if early sbrk fails
  <https://sourceware.org/pipermail/libc-alpha/2022-May/138331.html>

Stefan, I would appreciate if you could check that the kernel fixes are
not strictly required anymore with these changes.

Thanks,
Florian
  
Stefan Liebler May 3, 2022, 12:56 p.m. UTC | #4
On 02/05/2022 21:18, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> On 02/05/2022 06:13, Florian Weimer via Libc-alpha wrote:
>>> * Stefan Liebler via Libc-alpha:
>>>
>>>> This commit enables static PIE on 64bit.  On 31bit, static PIE is
>>>> not supported.
>>>>
>>>> - kernel (the mentioned links to the commits belong to 5.19 merge window):
>>>>   - "s390/mmap: increase stack/mmap gap to 128MB"
>>>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2
>>>>   - "s390/vdso: move vdso mapping to its own function"
>>>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8
>>>>   - "s390/vdso: map vdso above stack"
>>>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033
>>>>   - "s390/vdso: add vdso randomization"
>>>>     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25
>>>>   (We can't test the kernel of the target system)
>>>>   Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0),
>>>>   static PIE executables like ldconfig will crash.  While startup sbrk is
>>>>   used to enlarge the HEAP.  Unfortunately the underlying brk syscall fails
>>>>   as there is not enough space after the HEAP.  Then the address of the TLS
>>>>   image is invalid and the following memcpy in __libc_setup_tls() leads
>>>>   to a segfault.
>>>>   If /proc/sys/kernel/randomize_va_space is activated (default: 2), there
>>>>   is enough space after HEAP.
>>>
>>> I'll work an early allocator that does not use the TCB and which should
>>> avoid the sbrk crash.  Will that be sufficient to enable static PIE
>>> binaries to run on unchanged kernels?
>>>
>>> Otherwise I fear that we end up in a world of pain if we turn ldconfig
>>> into a static PIE binary. 8-(
>>
>>
>> I agree that ideally it should not rely a patched kernel to overcome the
>> glibc issue of handling sbrk call failures and having a working loader
>> allocator that work regardless of kernel version is the best approach. 
>>
>> As I put on weekly call, I would prefer to make it only use mmap as
>> for simplicity. 
> 
> Getting mmap to work is actually the hard part due to six-argument
> system call.  Trying sbrk first does not add much complexity.  I posted
> my series:
> 
>   Linux: Fall back to mmap if early sbrk fails
>   <https://sourceware.org/pipermail/libc-alpha/2022-May/138331.html>
> 
> Stefan, I would appreciate if you could check that the kernel fixes are
> not strictly required anymore with these changes.
> 
> Thanks,
> Florian
> 
Hi Florian and Adhemerval,

I've just build glibc-HEAD and run the testsuite with
/proc/sys/kernel/randomize_va_space = 0. => Recognized fails as srbk failed.

Then I've build with Florian's patch series on top. I don't see any
testsuite fails. Furthermore I've debbugged a static testcase into
_dl_early_allocate => mmap was used as result and previous was equal.

With Florian's patch series also applied, static PIE binaries also run
on an unchanged kernel.

Thanks,
Stefan
  
Florian Weimer May 3, 2022, 3:36 p.m. UTC | #5
* Stefan Liebler:

> I've just build glibc-HEAD and run the testsuite with
> /proc/sys/kernel/randomize_va_space = 0. => Recognized fails as srbk failed.
>
> Then I've build with Florian's patch series on top. I don't see any
> testsuite fails. Furthermore I've debbugged a static testcase into
> _dl_early_allocate => mmap was used as result and previous was equal.
>
> With Florian's patch series also applied, static PIE binaries also run
> on an unchanged kernel.

That's great.  Then I think this means it's safe to enable static PIE
for s390x.

Thanks,
Florian
  
Stefan Liebler May 4, 2022, 1:16 p.m. UTC | #6
On 03/05/2022 17:36, Florian Weimer wrote:
> * Stefan Liebler:
> 
>> I've just build glibc-HEAD and run the testsuite with
>> /proc/sys/kernel/randomize_va_space = 0. => Recognized fails as srbk failed.
>>
>> Then I've build with Florian's patch series on top. I don't see any
>> testsuite fails. Furthermore I've debbugged a static testcase into
>> _dl_early_allocate => mmap was used as result and previous was equal.
>>
>> With Florian's patch series also applied, static PIE binaries also run
>> on an unchanged kernel.
> 
> That's great.  Then I think this means it's safe to enable static PIE
> for s390x.
> 
> Thanks,
> Florian
> 

Thanks. Then I'll add some comments regarding your patch-series to
configure.ac before pushing.

Shall I wait until your patches are committed or is it okay if I push my
patch before?
  
Florian Weimer May 4, 2022, 1:39 p.m. UTC | #7
* Stefan Liebler:

> On 03/05/2022 17:36, Florian Weimer wrote:
>> * Stefan Liebler:
>> 
>>> I've just build glibc-HEAD and run the testsuite with
>>> /proc/sys/kernel/randomize_va_space = 0. => Recognized fails as srbk failed.
>>>
>>> Then I've build with Florian's patch series on top. I don't see any
>>> testsuite fails. Furthermore I've debbugged a static testcase into
>>> _dl_early_allocate => mmap was used as result and previous was equal.
>>>
>>> With Florian's patch series also applied, static PIE binaries also run
>>> on an unchanged kernel.
>> 
>> That's great.  Then I think this means it's safe to enable static PIE
>> for s390x.
>> 
>> Thanks,
>> Florian
>> 
>
> Thanks. Then I'll add some comments regarding your patch-series to
> configure.ac before pushing.
>
> Shall I wait until your patches are committed or is it okay if I push my
> patch before?

I think in isolation, it might break the Fedora builders and others.
I'll push the three approved patches today and repost the rest later
today.  Hopefully we can get this resolved by the end of this week.

Thanks,
Florian
  
Stefan Liebler May 19, 2022, 7:49 a.m. UTC | #8
On 04/05/2022 15:39, Florian Weimer wrote:
> * Stefan Liebler:
> 
>> On 03/05/2022 17:36, Florian Weimer wrote:
>>> * Stefan Liebler:
>>>
>>>> I've just build glibc-HEAD and run the testsuite with
>>>> /proc/sys/kernel/randomize_va_space = 0. => Recognized fails as srbk failed.
>>>>
>>>> Then I've build with Florian's patch series on top. I don't see any
>>>> testsuite fails. Furthermore I've debbugged a static testcase into
>>>> _dl_early_allocate => mmap was used as result and previous was equal.
>>>>
>>>> With Florian's patch series also applied, static PIE binaries also run
>>>> on an unchanged kernel.
>>>
>>> That's great.  Then I think this means it's safe to enable static PIE
>>> for s390x.
>>>
>>> Thanks,
>>> Florian
>>>
>>
>> Thanks. Then I'll add some comments regarding your patch-series to
>> configure.ac before pushing.
>>
>> Shall I wait until your patches are committed or is it okay if I push my
>> patch before?
> 
> I think in isolation, it might break the Fedora builders and others.
> I'll push the three approved patches today and repost the rest later
> today.  Hopefully we can get this resolved by the end of this week.
> 
> Thanks,
> Florian
> 

This commit is now pushed to master and glibc 2.35 release branch
(Florian's patch series is also already pushed to the release branch).

Thanks,
Stefan
  
Stefan Liebler May 19, 2022, 3:20 p.m. UTC | #9
On 19/05/2022 09:49, Stefan Liebler wrote:
> On 04/05/2022 15:39, Florian Weimer wrote:
>> * Stefan Liebler:
>>
>>> On 03/05/2022 17:36, Florian Weimer wrote:
>>>> * Stefan Liebler:
>>>>
>>>>> I've just build glibc-HEAD and run the testsuite with
>>>>> /proc/sys/kernel/randomize_va_space = 0. => Recognized fails as srbk failed.
>>>>>
>>>>> Then I've build with Florian's patch series on top. I don't see any
>>>>> testsuite fails. Furthermore I've debbugged a static testcase into
>>>>> _dl_early_allocate => mmap was used as result and previous was equal.
>>>>>
>>>>> With Florian's patch series also applied, static PIE binaries also run
>>>>> on an unchanged kernel.
>>>>
>>>> That's great.  Then I think this means it's safe to enable static PIE
>>>> for s390x.
>>>>
>>>> Thanks,
>>>> Florian
>>>>
>>>
>>> Thanks. Then I'll add some comments regarding your patch-series to
>>> configure.ac before pushing.
>>>
>>> Shall I wait until your patches are committed or is it okay if I push my
>>> patch before?
>>
>> I think in isolation, it might break the Fedora builders and others.
>> I'll push the three approved patches today and repost the rest later
>> today.  Hopefully we can get this resolved by the end of this week.
>>
>> Thanks,
>> Florian
>>
> 
> This commit is now pushed to master and glibc 2.35 release branch
> (Florian's patch series is also already pushed to the release branch).
> 
> Thanks,
> Stefan

Also committed to glibc 2.34 release branch
(Florian's patch series is also already pushed to the release branch).
  

Patch

diff --git a/sysdeps/s390/s390-64/configure b/sysdeps/s390/s390-64/configure
new file mode 100644
index 0000000000..1235523721
--- /dev/null
+++ b/sysdeps/s390/s390-64/configure
@@ -0,0 +1,104 @@ 
+# This file is generated from configure.ac by Autoconf.  DO NOT EDIT!
+ # Local configure fragment for sysdeps/s390/s390-64.
+
+# Minimal checking for static PIE support in ld.
+# Compare to ld testcase/bugzilla:
+# <binutils-source>/ld/testsuite/ld-elf/pr22263-1.rd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for s390-specific static PIE requirements" >&5
+$as_echo_n "checking for s390-specific static PIE requirements... " >&6; }
+if { as_var=\
+libc_cv_s390x_staticpie_req; eval \${$as_var+:} false; }; then :
+  $as_echo_n "(cached) " >&6
+else
+    cat > conftest1.c <<EOF
+__thread int * foo;
+
+void
+bar (void)
+{
+  *foo = 1;
+}
+EOF
+  cat > conftest2.c <<EOF
+extern __thread int *foo;
+extern void bar (void);
+static int x;
+
+int
+main ()
+{
+  foo = &x;
+  return 0;
+}
+EOF
+  libc_cv_s390x_staticpie_req=no
+  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIE -c conftest1.c -o conftest1.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } \
+     && { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIE -c conftest2.c -o conftest2.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } \
+     && { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -pie -o conftest conftest1.o conftest2.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } \
+     && { ac_try='! readelf -Wr conftest | grep R_390_TLS_TPOFF'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+  then
+    libc_cv_s390x_staticpie_req=yes
+  fi
+  rm -rf conftest.*
+fi
+eval ac_res=\$\
+libc_cv_s390x_staticpie_req
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if test $libc_cv_s390x_staticpie_req = yes; then
+   # Static PIE is supported only on 64bit.
+   # Ensure you also have those patches for:
+   # - binutils (ld)
+   #   - "[PR ld/22263] s390: Avoid dynamic TLS relocs in PIE"
+   #     https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=26b1426577b5dcb32d149c64cca3e603b81948a9
+   #     (Tested by configure check above)
+   #     Otherwise there will be a R_390_TLS_TPOFF relocation, which fails to
+   #     be processed in _dl_relocate_static_pie() as static TLS map is not setup.
+   #   - "s390: Add DT_JMPREL pointing to .rela.[i]plt with static-pie"
+   #     https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d942d8db12adf4c9e5c7d9ed6496a779ece7149e
+   #     (We can't test it in configure as we are not able to link a static PIE
+   #     executable if the system glibc lacks static PIE support)
+   #     Otherwise there won't be DT_JMPREL, DT_PLTRELA, DT_PLTRELASZ entries
+   #     and the IFUNC symbols are not processed, which leads to crashes.
+   #
+   # - kernel (the mentioned links to the commits belong to 5.19 merge window):
+   #   - "s390/mmap: increase stack/mmap gap to 128MB"
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2
+   #   - "s390/vdso: move vdso mapping to its own function"
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8
+   #   - "s390/vdso: map vdso above stack"
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033
+   #   - "s390/vdso: add vdso randomization"
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25
+   #   (We can't test the kernel of the target system)
+   #   Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0),
+   #   static PIE executables like ldconfig will crash.  While startup sbrk is
+   #   used to enlarge the HEAP.  Unfortunately the underlying brk syscall fails
+   #   as there is not enough space after the HEAP.  Then the address of the TLS
+   #   image is invalid and the following memcpy in __libc_setup_tls() leads
+   #   to a segfault.
+   #   If /proc/sys/kernel/randomize_va_space is activated (default: 2), there
+   #   is enough space after HEAP.
+   $as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h
+
+fi
diff --git a/sysdeps/s390/s390-64/configure.ac b/sysdeps/s390/s390-64/configure.ac
new file mode 100644
index 0000000000..9f6da565f9
--- /dev/null
+++ b/sysdeps/s390/s390-64/configure.ac
@@ -0,0 +1,74 @@ 
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/s390/s390-64.
+
+# Minimal checking for static PIE support in ld.
+# Compare to ld testcase/bugzilla:
+# <binutils-source>/ld/testsuite/ld-elf/pr22263-1.rd
+AC_CACHE_CHECK([for s390-specific static PIE requirements], \
+[libc_cv_s390x_staticpie_req], [dnl
+  cat > conftest1.c <<EOF
+__thread int * foo;
+
+void
+bar (void)
+{
+  *foo = 1;
+}
+EOF
+  cat > conftest2.c <<EOF
+extern __thread int *foo;
+extern void bar (void);
+static int x;
+
+int
+main ()
+{
+  foo = &x;
+  return 0;
+}
+EOF
+  libc_cv_s390x_staticpie_req=no
+  if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIE -c conftest1.c -o conftest1.o]) \
+     && AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIE -c conftest2.c -o conftest2.o]) \
+     && AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -pie -o conftest conftest1.o conftest2.o]) \
+     && AC_TRY_COMMAND([! readelf -Wr conftest | grep R_390_TLS_TPOFF])
+  then
+    libc_cv_s390x_staticpie_req=yes
+  fi
+  rm -rf conftest.*])
+if test $libc_cv_s390x_staticpie_req = yes; then
+   # Static PIE is supported only on 64bit.
+   # Ensure you also have those patches for:
+   # - binutils (ld)
+   #   - "[PR ld/22263] s390: Avoid dynamic TLS relocs in PIE"
+   #     https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=26b1426577b5dcb32d149c64cca3e603b81948a9
+   #     (Tested by configure check above)
+   #     Otherwise there will be a R_390_TLS_TPOFF relocation, which fails to
+   #     be processed in _dl_relocate_static_pie() as static TLS map is not setup.
+   #   - "s390: Add DT_JMPREL pointing to .rela.[i]plt with static-pie"
+   #     https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d942d8db12adf4c9e5c7d9ed6496a779ece7149e
+   #     (We can't test it in configure as we are not able to link a static PIE
+   #     executable if the system glibc lacks static PIE support)
+   #     Otherwise there won't be DT_JMPREL, DT_PLTRELA, DT_PLTRELASZ entries
+   #     and the IFUNC symbols are not processed, which leads to crashes.
+   #
+   # - kernel (the mentioned links to the commits belong to 5.19 merge window):
+   #   - "s390/mmap: increase stack/mmap gap to 128MB"
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2
+   #   - "s390/vdso: move vdso mapping to its own function"
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8
+   #   - "s390/vdso: map vdso above stack"
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033
+   #   - "s390/vdso: add vdso randomization"
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25
+   #   (We can't test the kernel of the target system)
+   #   Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0),
+   #   static PIE executables like ldconfig will crash.  While startup sbrk is
+   #   used to enlarge the HEAP.  Unfortunately the underlying brk syscall fails
+   #   as there is not enough space after the HEAP.  Then the address of the TLS
+   #   image is invalid and the following memcpy in __libc_setup_tls() leads
+   #   to a segfault.
+   #   If /proc/sys/kernel/randomize_va_space is activated (default: 2), there
+   #   is enough space after HEAP.
+   AC_DEFINE(SUPPORT_STATIC_PIE)
+fi
diff --git a/sysdeps/s390/s390-64/start.S b/sysdeps/s390/s390-64/start.S
index 33c1302049..f4c3f51315 100644
--- a/sysdeps/s390/s390-64/start.S
+++ b/sysdeps/s390/s390-64/start.S
@@ -84,10 +84,25 @@  _start:
 
 	/* Ok, now branch to the libc main routine.  */
 #ifdef PIC
+# ifdef SHARED
+	/* Used for dynamic linked position independent executable.
+	   => Scrt1.o  */
 	larl	%r2,main@GOTENT		# load pointer to main
 	lg	%r2,0(%r2)
+# else
+	/* Used for dynamic linked position dependent executable.
+	   => crt1.o (glibc configured without --disable-default-pie:
+	   PIC is defined)
+	   Or for static linked position independent executable.
+	   => rcrt1.o (only available if glibc configured without
+	   --disable-default-pie: PIC is defined) */
+	larl	%r2,__wrap_main
+# endif
 	brasl	%r14,__libc_start_main@plt
 #else
+	/* Used for dynamic/static linked position dependent executable.
+	   => crt1.o (glibc configured with --disable-default-pie:
+	   PIC and SHARED are not defined)  */
 	larl	%r2,main		# load pointer to main
 	brasl	%r14,__libc_start_main
 #endif
@@ -97,6 +112,19 @@  _start:
 
 	cfi_endproc
 
+#if defined PIC && !defined SHARED
+	/* When main is not defined in the executable but in a shared library
+	   then a wrapper is needed in crt1.o of the static-pie enabled libc,
+	   because crt1.o and rcrt1.o share code and the later must avoid the
+	   use of GOT relocations before __libc_start_main is called.  */
+__wrap_main:
+	cfi_startproc
+	larl	%r1,main@GOTENT		# load pointer to main
+	lg	%r1,0(%r1)
+	br	%r1
+	cfi_endproc
+#endif
+
 	/* Define a symbol for the first piece of initialized data.  */
 	.data
 	.globl __data_start