mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-29 16:21:07 +00:00
728894dba4
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. - glibc - "Linux: Define MMAP_CALL_INTERNAL" https://sourceware.org/git/?p=glibc.git;a=commit;h=c1b68685d438373efe64e5f076f4215723004dfb - "i386: Remove OPTIMIZE_FOR_GCC_5 from Linux libc-do-syscall.S" https://sourceware.org/git/?p=glibc.git;a=commit;h=6e5c7a1e262961adb52443ab91bd2c9b72316402 - "i386: Honor I386_USE_SYSENTER for 6-argument Linux system calls" https://sourceware.org/git/?p=glibc.git;a=commit;h=60f0f2130d30cfd008ca39743027f1e200592dff - "ia64: Always define IA64_USE_NEW_STUB as a flag macro" https://sourceware.org/git/?p=glibc.git;a=commit;h=18bd9c3d3b1b6a9182698c85354578d1d58e9d64 - "Linux: Implement a useful version of _startup_fatal" https://sourceware.org/git/?p=glibc.git;a=commit;h=a2a6bce7d7e52c1c34369a7da62c501cc350bc31 - "Linux: Introduce __brk_call for invoking the brk system call" https://sourceware.org/git/?p=glibc.git;a=commit;h=b57ab258c1140bc45464b4b9908713e3e0ee35aa - "csu: Implement and use _dl_early_allocate during static startup" https://sourceware.org/git/?p=glibc.git;a=commit;h=f787e138aa0bf677bf74fa2a08595c446292f3d7 The mentioned patch series by Florian Weimer avoids the mentioned failing sbrk syscall by falling back to mmap. 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: - commit14d886edbd
"aarch64: fix start code for static pie" - commit3d1d79283e
"aarch64: fix static pie enabled libc when main is in a shared library" )
135 lines
4.5 KiB
ArmAsm
135 lines
4.5 KiB
ArmAsm
/* Startup code compliant to the 64 bit S/390 ELF ABI.
|
|
Copyright (C) 2001-2022 Free Software Foundation, Inc.
|
|
This file is part of the GNU C Library.
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
In addition to the permissions in the GNU Lesser General Public
|
|
License, the Free Software Foundation gives you unlimited
|
|
permission to link the compiled version of this file with other
|
|
programs, and to distribute those programs without any restriction
|
|
coming from the use of this file. (The GNU Lesser General Public
|
|
License restrictions do apply in other respects; for example, they
|
|
cover modification of the file, and distribution when not linked
|
|
into another program.)
|
|
|
|
Note that people who make modified versions of this file are not
|
|
obligated to grant this special exception for their modified
|
|
versions; it is their choice whether to do so. The GNU Lesser
|
|
General Public License gives permission to release a modified
|
|
version without this exception; this exception also makes it
|
|
possible to release a modified version which carries forward this
|
|
exception.
|
|
|
|
The GNU C Library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with the GNU C Library; if not, see
|
|
<https://www.gnu.org/licenses/>. */
|
|
|
|
#include <sysdep.h>
|
|
|
|
/*
|
|
This is the canonical entry point, usually the first thing in the text
|
|
segment. Most registers' values are unspecified, except for:
|
|
|
|
%r14 Contains a function pointer to be registered with `atexit'.
|
|
This is how the dynamic linker arranges to have DT_FINI
|
|
functions called for shared libraries that have been loaded
|
|
before this code runs.
|
|
|
|
%r15 The stack contains the arguments and environment:
|
|
0(%r15) argc
|
|
8(%r15) argv[0]
|
|
...
|
|
(8*argc)(%r15) NULL
|
|
(8*(argc+1))(%r15) envp[0]
|
|
...
|
|
NULL
|
|
*/
|
|
|
|
.text
|
|
.globl _start
|
|
.type _start,@function
|
|
_start:
|
|
cfi_startproc
|
|
/* Mark r14 as undefined in order to stop unwinding here! */
|
|
cfi_undefined (r14)
|
|
/* Load argc and argv from stack. */
|
|
la %r4,8(%r15) # get argv
|
|
lg %r3,0(%r15) # get argc
|
|
|
|
/* Align the stack to a double word boundary. */
|
|
lghi %r0,-16
|
|
ngr %r15,%r0
|
|
|
|
/* Setup a stack frame and a parameter area. */
|
|
aghi %r15,-176 # make room on stack
|
|
xc 0(8,%r15),0(%r15) # clear back-chain
|
|
|
|
/* Set up arguments for __libc_start_main:
|
|
main, argc, argv, envp, _init, _fini, rtld_fini, stack_end
|
|
Note that envp will be determined later in __libc_start_main.
|
|
*/
|
|
stmg %r14,%r15,160(%r15) # store rtld_fini/stack_end to parameter area
|
|
la %r7,160(%r15)
|
|
lghi %r6,0 # Used to be fini.
|
|
lghi %r5,0 # Used to be init.
|
|
|
|
/* 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
|
|
|
|
/* Crash if __libc_start_main returns. */
|
|
.word 0
|
|
|
|
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
|
|
__data_start:
|
|
.long 0
|
|
.weak data_start
|
|
data_start = __data_start
|