08c3a6
commit 89b638f48ac5c9af5b1fe9caa6287d70127b66a5
08c3a6
Author: Stefan Liebler <stli@linux.ibm.com>
08c3a6
Date:   Tue May 17 16:12:18 2022 +0200
08c3a6
08c3a6
    S390: Enable static PIE
08c3a6
    
08c3a6
    This commit enables static PIE on 64bit.  On 31bit, static PIE is
08c3a6
    not supported.
08c3a6
    
08c3a6
    A new configure check in sysdeps/s390/s390-64/configure.ac also performs
08c3a6
    a minimal test for requirements in ld:
08c3a6
    Ensure you also have those patches for:
08c3a6
    - binutils (ld)
08c3a6
      - "[PR ld/22263] s390: Avoid dynamic TLS relocs in PIE"
08c3a6
        https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=26b1426577b5dcb32d149c64cca3e603b81948a9
08c3a6
        (Tested by configure check above)
08c3a6
        Otherwise there will be a R_390_TLS_TPOFF relocation, which fails to
08c3a6
        be processed in _dl_relocate_static_pie() as static TLS map is not setup.
08c3a6
      - "s390: Add DT_JMPREL pointing to .rela.[i]plt with static-pie"
08c3a6
        https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d942d8db12adf4c9e5c7d9ed6496a779ece7149e
08c3a6
        (We can't test it in configure as we are not able to link a static PIE
08c3a6
        executable if the system glibc lacks static PIE support)
08c3a6
        Otherwise there won't be DT_JMPREL, DT_PLTRELA, DT_PLTRELASZ entries
08c3a6
        and the IFUNC symbols are not processed, which leads to crashes.
08c3a6
    
08c3a6
    - kernel (the mentioned links to the commits belong to 5.19 merge window):
08c3a6
      - "s390/mmap: increase stack/mmap gap to 128MB"
08c3a6
        https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2
08c3a6
      - "s390/vdso: move vdso mapping to its own function"
08c3a6
        https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8
08c3a6
      - "s390/vdso: map vdso above stack"
08c3a6
        https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033
08c3a6
      - "s390/vdso: add vdso randomization"
08c3a6
        https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25
08c3a6
      (We can't test the kernel of the target system)
08c3a6
      Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0),
08c3a6
      static PIE executables like ldconfig will crash.  While startup sbrk is
08c3a6
      used to enlarge the HEAP.  Unfortunately the underlying brk syscall fails
08c3a6
      as there is not enough space after the HEAP.  Then the address of the TLS
08c3a6
      image is invalid and the following memcpy in __libc_setup_tls() leads
08c3a6
      to a segfault.
08c3a6
      If /proc/sys/kernel/randomize_va_space is activated (default: 2), there
08c3a6
      is enough space after HEAP.
08c3a6
    
08c3a6
    - glibc
08c3a6
      - "Linux: Define MMAP_CALL_INTERNAL"
08c3a6
        https://sourceware.org/git/?p=glibc.git;a=commit;h=c1b68685d438373efe64e5f076f4215723004dfb
08c3a6
      - "i386: Remove OPTIMIZE_FOR_GCC_5 from Linux libc-do-syscall.S"
08c3a6
        https://sourceware.org/git/?p=glibc.git;a=commit;h=6e5c7a1e262961adb52443ab91bd2c9b72316402
08c3a6
      - "i386: Honor I386_USE_SYSENTER for 6-argument Linux system calls"
08c3a6
        https://sourceware.org/git/?p=glibc.git;a=commit;h=60f0f2130d30cfd008ca39743027f1e200592dff
08c3a6
      - "ia64: Always define IA64_USE_NEW_STUB as a flag macro"
08c3a6
        https://sourceware.org/git/?p=glibc.git;a=commit;h=18bd9c3d3b1b6a9182698c85354578d1d58e9d64
08c3a6
      - "Linux: Implement a useful version of _startup_fatal"
08c3a6
        https://sourceware.org/git/?p=glibc.git;a=commit;h=a2a6bce7d7e52c1c34369a7da62c501cc350bc31
08c3a6
      - "Linux: Introduce __brk_call for invoking the brk system call"
08c3a6
        https://sourceware.org/git/?p=glibc.git;a=commit;h=b57ab258c1140bc45464b4b9908713e3e0ee35aa
08c3a6
      - "csu: Implement and use _dl_early_allocate during static startup"
08c3a6
        https://sourceware.org/git/?p=glibc.git;a=commit;h=f787e138aa0bf677bf74fa2a08595c446292f3d7
08c3a6
      The mentioned patch series by Florian Weimer avoids the mentioned failing
08c3a6
      sbrk syscall by falling back to mmap.
08c3a6
    
08c3a6
    This commit also adjusts startup code in start.S to be ready for static PIE.
08c3a6
    We have to add a wrapper function for main as we are not allowed to use
08c3a6
    GOT relocations before __libc_start_main is called.
08c3a6
    (Compare also to:
08c3a6
    - commit 14d886edbd3d80b771e1c42fbd9217f9074de9c6
08c3a6
      "aarch64: fix start code for static pie"
08c3a6
    - commit 3d1d79283e6de4f7c434cb67fb53a4fd28359669
08c3a6
      "aarch64: fix static pie enabled libc when main is in a shared library"
08c3a6
    )
08c3a6
    
08c3a6
    (cherry picked from commit 728894dba4a19578bd803906de184a8dd51ed13c)
08c3a6
08c3a6
diff --git a/sysdeps/s390/s390-64/configure b/sysdeps/s390/s390-64/configure
08c3a6
new file mode 100644
08c3a6
index 0000000000000000..101c570d2e62da25
08c3a6
--- /dev/null
08c3a6
+++ b/sysdeps/s390/s390-64/configure
08c3a6
@@ -0,0 +1,122 @@
08c3a6
+# This file is generated from configure.ac by Autoconf.  DO NOT EDIT!
08c3a6
+ # Local configure fragment for sysdeps/s390/s390-64.
08c3a6
+
08c3a6
+# Minimal checking for static PIE support in ld.
08c3a6
+# Compare to ld testcase/bugzilla:
08c3a6
+# <binutils-source>/ld/testsuite/ld-elf/pr22263-1.rd
08c3a6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for s390-specific static PIE requirements" >&5
08c3a6
+$as_echo_n "checking for s390-specific static PIE requirements... " >&6; }
08c3a6
+if { as_var=\
08c3a6
+libc_cv_s390x_staticpie_req; eval \${$as_var+:} false; }; then :
08c3a6
+  $as_echo_n "(cached) " >&6
08c3a6
+else
08c3a6
+    cat > conftest1.c <
08c3a6
+__thread int * foo;
08c3a6
+
08c3a6
+void
08c3a6
+bar (void)
08c3a6
+{
08c3a6
+  *foo = 1;
08c3a6
+}
08c3a6
+EOF
08c3a6
+  cat > conftest2.c <
08c3a6
+extern __thread int *foo;
08c3a6
+extern void bar (void);
08c3a6
+static int x;
08c3a6
+
08c3a6
+int
08c3a6
+main ()
08c3a6
+{
08c3a6
+  foo = &x;
08c3a6
+  return 0;
08c3a6
+}
08c3a6
+EOF
08c3a6
+  libc_cv_s390x_staticpie_req=no
08c3a6
+  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIE -c conftest1.c -o conftest1.o'
08c3a6
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
08c3a6
+  (eval $ac_try) 2>&5
08c3a6
+  ac_status=$?
08c3a6
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
08c3a6
+  test $ac_status = 0; }; } \
08c3a6
+     && { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIE -c conftest2.c -o conftest2.o'
08c3a6
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
08c3a6
+  (eval $ac_try) 2>&5
08c3a6
+  ac_status=$?
08c3a6
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
08c3a6
+  test $ac_status = 0; }; } \
08c3a6
+     && { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -pie -o conftest conftest1.o conftest2.o'
08c3a6
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
08c3a6
+  (eval $ac_try) 2>&5
08c3a6
+  ac_status=$?
08c3a6
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
08c3a6
+  test $ac_status = 0; }; } \
08c3a6
+     && { ac_try='! readelf -Wr conftest | grep R_390_TLS_TPOFF'
08c3a6
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
08c3a6
+  (eval $ac_try) 2>&5
08c3a6
+  ac_status=$?
08c3a6
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
08c3a6
+  test $ac_status = 0; }; }
08c3a6
+  then
08c3a6
+    libc_cv_s390x_staticpie_req=yes
08c3a6
+  fi
08c3a6
+  rm -rf conftest.*
08c3a6
+fi
08c3a6
+eval ac_res=\$\
08c3a6
+libc_cv_s390x_staticpie_req
08c3a6
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
08c3a6
+$as_echo "$ac_res" >&6; }
08c3a6
+if test $libc_cv_s390x_staticpie_req = yes; then
08c3a6
+   # Static PIE is supported only on 64bit.
08c3a6
+   # Ensure you also have those patches for:
08c3a6
+   # - binutils (ld)
08c3a6
+   #   - "[PR ld/22263] s390: Avoid dynamic TLS relocs in PIE"
08c3a6
+   #     https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=26b1426577b5dcb32d149c64cca3e603b81948a9
08c3a6
+   #     (Tested by configure check above)
08c3a6
+   #     Otherwise there will be a R_390_TLS_TPOFF relocation, which fails to
08c3a6
+   #     be processed in _dl_relocate_static_pie() as static TLS map is not setup.
08c3a6
+   #   - "s390: Add DT_JMPREL pointing to .rela.[i]plt with static-pie"
08c3a6
+   #     https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d942d8db12adf4c9e5c7d9ed6496a779ece7149e
08c3a6
+   #     (We can't test it in configure as we are not able to link a static PIE
08c3a6
+   #     executable if the system glibc lacks static PIE support)
08c3a6
+   #     Otherwise there won't be DT_JMPREL, DT_PLTRELA, DT_PLTRELASZ entries
08c3a6
+   #     and the IFUNC symbols are not processed, which leads to crashes.
08c3a6
+   #
08c3a6
+   # - kernel (the mentioned links to the commits belong to 5.19 merge window):
08c3a6
+   #   - "s390/mmap: increase stack/mmap gap to 128MB"
08c3a6
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2
08c3a6
+   #   - "s390/vdso: move vdso mapping to its own function"
08c3a6
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8
08c3a6
+   #   - "s390/vdso: map vdso above stack"
08c3a6
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033
08c3a6
+   #   - "s390/vdso: add vdso randomization"
08c3a6
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25
08c3a6
+   #   (We can't test the kernel of the target system)
08c3a6
+   #   Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0),
08c3a6
+   #   static PIE executables like ldconfig will crash.  While startup sbrk is
08c3a6
+   #   used to enlarge the HEAP.  Unfortunately the underlying brk syscall fails
08c3a6
+   #   as there is not enough space after the HEAP.  Then the address of the TLS
08c3a6
+   #   image is invalid and the following memcpy in __libc_setup_tls() leads
08c3a6
+   #   to a segfault.
08c3a6
+   #   If /proc/sys/kernel/randomize_va_space is activated (default: 2), there
08c3a6
+   #   is enough space after HEAP.
08c3a6
+   #
08c3a6
+   # - glibc
08c3a6
+   #   - "Linux: Define MMAP_CALL_INTERNAL"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=c1b68685d438373efe64e5f076f4215723004dfb
08c3a6
+   #   - "i386: Remove OPTIMIZE_FOR_GCC_5 from Linux libc-do-syscall.S"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=6e5c7a1e262961adb52443ab91bd2c9b72316402
08c3a6
+   #   - "i386: Honor I386_USE_SYSENTER for 6-argument Linux system calls"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=60f0f2130d30cfd008ca39743027f1e200592dff
08c3a6
+   #   - "ia64: Always define IA64_USE_NEW_STUB as a flag macro"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=18bd9c3d3b1b6a9182698c85354578d1d58e9d64
08c3a6
+   #   - "Linux: Implement a useful version of _startup_fatal"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=a2a6bce7d7e52c1c34369a7da62c501cc350bc31
08c3a6
+   #   - "Linux: Introduce __brk_call for invoking the brk system call"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=b57ab258c1140bc45464b4b9908713e3e0ee35aa
08c3a6
+   #   - "csu: Implement and use _dl_early_allocate during static startup"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=f787e138aa0bf677bf74fa2a08595c446292f3d7
08c3a6
+   #   The mentioned patch series by Florian Weimer avoids the mentioned failing
08c3a6
+   #   sbrk syscall by falling back to mmap.
08c3a6
+   $as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h
08c3a6
+
08c3a6
+fi
08c3a6
diff --git a/sysdeps/s390/s390-64/configure.ac b/sysdeps/s390/s390-64/configure.ac
08c3a6
new file mode 100644
08c3a6
index 0000000000000000..2583a4a3350ac11f
08c3a6
--- /dev/null
08c3a6
+++ b/sysdeps/s390/s390-64/configure.ac
08c3a6
@@ -0,0 +1,92 @@
08c3a6
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
08c3a6
+# Local configure fragment for sysdeps/s390/s390-64.
08c3a6
+
08c3a6
+# Minimal checking for static PIE support in ld.
08c3a6
+# Compare to ld testcase/bugzilla:
08c3a6
+# <binutils-source>/ld/testsuite/ld-elf/pr22263-1.rd
08c3a6
+AC_CACHE_CHECK([for s390-specific static PIE requirements], \
08c3a6
+[libc_cv_s390x_staticpie_req], [dnl
08c3a6
+  cat > conftest1.c <
08c3a6
+__thread int * foo;
08c3a6
+
08c3a6
+void
08c3a6
+bar (void)
08c3a6
+{
08c3a6
+  *foo = 1;
08c3a6
+}
08c3a6
+EOF
08c3a6
+  cat > conftest2.c <
08c3a6
+extern __thread int *foo;
08c3a6
+extern void bar (void);
08c3a6
+static int x;
08c3a6
+
08c3a6
+int
08c3a6
+main ()
08c3a6
+{
08c3a6
+  foo = &x;
08c3a6
+  return 0;
08c3a6
+}
08c3a6
+EOF
08c3a6
+  libc_cv_s390x_staticpie_req=no
08c3a6
+  if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIE -c conftest1.c -o conftest1.o]) \
08c3a6
+     && AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIE -c conftest2.c -o conftest2.o]) \
08c3a6
+     && AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -pie -o conftest conftest1.o conftest2.o]) \
08c3a6
+     && AC_TRY_COMMAND([! readelf -Wr conftest | grep R_390_TLS_TPOFF])
08c3a6
+  then
08c3a6
+    libc_cv_s390x_staticpie_req=yes
08c3a6
+  fi
08c3a6
+  rm -rf conftest.*])
08c3a6
+if test $libc_cv_s390x_staticpie_req = yes; then
08c3a6
+   # Static PIE is supported only on 64bit.
08c3a6
+   # Ensure you also have those patches for:
08c3a6
+   # - binutils (ld)
08c3a6
+   #   - "[PR ld/22263] s390: Avoid dynamic TLS relocs in PIE"
08c3a6
+   #     https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=26b1426577b5dcb32d149c64cca3e603b81948a9
08c3a6
+   #     (Tested by configure check above)
08c3a6
+   #     Otherwise there will be a R_390_TLS_TPOFF relocation, which fails to
08c3a6
+   #     be processed in _dl_relocate_static_pie() as static TLS map is not setup.
08c3a6
+   #   - "s390: Add DT_JMPREL pointing to .rela.[i]plt with static-pie"
08c3a6
+   #     https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d942d8db12adf4c9e5c7d9ed6496a779ece7149e
08c3a6
+   #     (We can't test it in configure as we are not able to link a static PIE
08c3a6
+   #     executable if the system glibc lacks static PIE support)
08c3a6
+   #     Otherwise there won't be DT_JMPREL, DT_PLTRELA, DT_PLTRELASZ entries
08c3a6
+   #     and the IFUNC symbols are not processed, which leads to crashes.
08c3a6
+   #
08c3a6
+   # - kernel (the mentioned links to the commits belong to 5.19 merge window):
08c3a6
+   #   - "s390/mmap: increase stack/mmap gap to 128MB"
08c3a6
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=f2f47d0ef72c30622e62471903ea19446ea79ee2
08c3a6
+   #   - "s390/vdso: move vdso mapping to its own function"
08c3a6
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=57761da4dc5cd60bed2c81ba0edb7495c3c740b8
08c3a6
+   #   - "s390/vdso: map vdso above stack"
08c3a6
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=9e37a2e8546f9e48ea76c839116fa5174d14e033
08c3a6
+   #   - "s390/vdso: add vdso randomization"
08c3a6
+   #     https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=features&id=41cd81abafdc4e58a93fcb677712a76885e3ca25
08c3a6
+   #   (We can't test the kernel of the target system)
08c3a6
+   #   Otherwise if /proc/sys/kernel/randomize_va_space is turned off (0),
08c3a6
+   #   static PIE executables like ldconfig will crash.  While startup sbrk is
08c3a6
+   #   used to enlarge the HEAP.  Unfortunately the underlying brk syscall fails
08c3a6
+   #   as there is not enough space after the HEAP.  Then the address of the TLS
08c3a6
+   #   image is invalid and the following memcpy in __libc_setup_tls() leads
08c3a6
+   #   to a segfault.
08c3a6
+   #   If /proc/sys/kernel/randomize_va_space is activated (default: 2), there
08c3a6
+   #   is enough space after HEAP.
08c3a6
+   #
08c3a6
+   # - glibc
08c3a6
+   #   - "Linux: Define MMAP_CALL_INTERNAL"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=c1b68685d438373efe64e5f076f4215723004dfb
08c3a6
+   #   - "i386: Remove OPTIMIZE_FOR_GCC_5 from Linux libc-do-syscall.S"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=6e5c7a1e262961adb52443ab91bd2c9b72316402
08c3a6
+   #   - "i386: Honor I386_USE_SYSENTER for 6-argument Linux system calls"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=60f0f2130d30cfd008ca39743027f1e200592dff
08c3a6
+   #   - "ia64: Always define IA64_USE_NEW_STUB as a flag macro"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=18bd9c3d3b1b6a9182698c85354578d1d58e9d64
08c3a6
+   #   - "Linux: Implement a useful version of _startup_fatal"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=a2a6bce7d7e52c1c34369a7da62c501cc350bc31
08c3a6
+   #   - "Linux: Introduce __brk_call for invoking the brk system call"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=b57ab258c1140bc45464b4b9908713e3e0ee35aa
08c3a6
+   #   - "csu: Implement and use _dl_early_allocate during static startup"
08c3a6
+   #     https://sourceware.org/git/?p=glibc.git;a=commit;h=f787e138aa0bf677bf74fa2a08595c446292f3d7
08c3a6
+   #   The mentioned patch series by Florian Weimer avoids the mentioned failing
08c3a6
+   #   sbrk syscall by falling back to mmap.
08c3a6
+   AC_DEFINE(SUPPORT_STATIC_PIE)
08c3a6
+fi
08c3a6
diff --git a/sysdeps/s390/s390-64/start.S b/sysdeps/s390/s390-64/start.S
08c3a6
index 4e6526308aee3c00..b4a66e4a97b83397 100644
08c3a6
--- a/sysdeps/s390/s390-64/start.S
08c3a6
+++ b/sysdeps/s390/s390-64/start.S
08c3a6
@@ -85,10 +85,25 @@ _start:
08c3a6
 
08c3a6
 	/* Ok, now branch to the libc main routine.  */
08c3a6
 #ifdef PIC
08c3a6
+# ifdef SHARED
08c3a6
+	/* Used for dynamic linked position independent executable.
08c3a6
+	   => Scrt1.o  */
08c3a6
 	larl	%r2,main@GOTENT		# load pointer to main
08c3a6
 	lg	%r2,0(%r2)
08c3a6
+# else
08c3a6
+	/* Used for dynamic linked position dependent executable.
08c3a6
+	   => crt1.o (glibc configured without --disable-default-pie:
08c3a6
+	   PIC is defined)
08c3a6
+	   Or for static linked position independent executable.
08c3a6
+	   => rcrt1.o (only available if glibc configured without
08c3a6
+	   --disable-default-pie: PIC is defined) */
08c3a6
+	larl	%r2,__wrap_main
08c3a6
+# endif
08c3a6
 	brasl	%r14,__libc_start_main@plt
08c3a6
 #else
08c3a6
+	/* Used for dynamic/static linked position dependent executable.
08c3a6
+	   => crt1.o (glibc configured with --disable-default-pie:
08c3a6
+	   PIC and SHARED are not defined)  */
08c3a6
 	larl	%r2,main		# load pointer to main
08c3a6
 	brasl	%r14,__libc_start_main
08c3a6
 #endif
08c3a6
@@ -98,6 +113,19 @@ _start:
08c3a6
 
08c3a6
 	cfi_endproc
08c3a6
 
08c3a6
+#if defined PIC && !defined SHARED
08c3a6
+	/* When main is not defined in the executable but in a shared library
08c3a6
+	   then a wrapper is needed in crt1.o of the static-pie enabled libc,
08c3a6
+	   because crt1.o and rcrt1.o share code and the later must avoid the
08c3a6
+	   use of GOT relocations before __libc_start_main is called.  */
08c3a6
+__wrap_main:
08c3a6
+	cfi_startproc
08c3a6
+	larl	%r1,main@GOTENT		# load pointer to main
08c3a6
+	lg	%r1,0(%r1)
08c3a6
+	br	%r1
08c3a6
+	cfi_endproc
08c3a6
+#endif
08c3a6
+
08c3a6
 	/* Define a symbol for the first piece of initialized data.  */
08c3a6
 	.data
08c3a6
 	.globl __data_start