glibc: restore compatibility with glibc<=2.33 for global initializers

__libc_start_main() from glibc.2.33.so or older needs to have a __libc_csu_init function callback parameter.

glibc-2.34 on the other hand has a different __libc_start_main() that does not use it,
and the start.S file from glibc-2.34 no longer construct the init function and pass null when calling __libc_start_main.

So, When targetting an older glibc, use the start.s files as they were in glibc-2.33 and construct the __libc_csu_init function.

fixes #10386 #10512
This commit is contained in:
xavier 2022-01-13 09:15:41 +01:00 committed by Andrew Kelley
parent a64989ee70
commit f1b14b91f1
20 changed files with 2345 additions and 5 deletions

106
lib/libc/glibc/csu/elf-init-2-33.c vendored Normal file
View File

@ -0,0 +1,106 @@
/* Startup support for ELF initializers/finalizers in the main executable.
Copyright (C) 2002-2020 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 <stddef.h>
/* These magic symbols are provided by the linker. */
extern void (*__preinit_array_start []) (int, char **, char **)
attribute_hidden;
extern void (*__preinit_array_end []) (int, char **, char **)
attribute_hidden;
extern void (*__init_array_start []) (int, char **, char **)
attribute_hidden;
extern void (*__init_array_end []) (int, char **, char **)
attribute_hidden;
extern void (*__fini_array_start []) (void) attribute_hidden;
extern void (*__fini_array_end []) (void) attribute_hidden;
#ifndef NO_INITFINI
/* These function symbols are provided for the .init/.fini section entry
points automagically by the linker. */
extern void _init (void);
extern void _fini (void);
#endif
/* These functions are passed to __libc_start_main by the startup code.
These get statically linked into each program. For dynamically linked
programs, this module will come from libc_nonshared.a and differs from
the libc.a module in that it doesn't call the preinit array. */
void
__libc_csu_init (int argc, char **argv, char **envp)
{
/* For dynamically linked executables the preinit array is executed by
the dynamic linker (before initializing any shared object). */
#ifndef LIBC_NONSHARED
/* For static executables, preinit happens right before init. */
{
const size_t size = __preinit_array_end - __preinit_array_start;
size_t i;
for (i = 0; i < size; i++)
(*__preinit_array_start [i]) (argc, argv, envp);
}
#endif
#ifndef NO_INITFINI
_init ();
#endif
const size_t size = __init_array_end - __init_array_start;
for (size_t i = 0; i < size; i++)
(*__init_array_start [i]) (argc, argv, envp);
}
/* This function should not be used anymore. We run the executable's
destructor now just like any other. We cannot remove the function,
though. */
void
__libc_csu_fini (void)
{
#ifndef LIBC_NONSHARED
size_t i = __fini_array_end - __fini_array_start;
while (i-- > 0)
(*__fini_array_start [i]) ();
# ifndef NO_INITFINI
_fini ();
# endif
#endif
}

View File

@ -0,0 +1,112 @@
/* Copyright (C) 1995-2020 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.
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.
Note that the code in the .init section has already been run.
This includes _init and _libc_init
At this entry point, most registers' values are unspecified, except:
x0/w0 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.
sp The stack contains the arguments and environment:
0(sp) argc
8(sp) argv[0]
...
(8*argc)(sp) NULL
(8*(argc+1))(sp) envp[0]
...
NULL
*/
.text
.globl _start
.type _start,#function
_start:
/* Create an initial frame with 0 LR and FP */
mov x29, #0
mov x30, #0
/* Setup rtld_fini in argument register */
mov x5, x0
/* Load argc and a pointer to argv */
ldr PTR_REG (1), [sp, #0]
add x2, sp, #PTR_SIZE
/* Setup stack limit in argument register */
mov x6, sp
#ifdef PIC
# ifdef SHARED
adrp x0, :got:main
ldr PTR_REG (0), [x0, #:got_lo12:main]
adrp x3, :got:__libc_csu_init
ldr PTR_REG (3), [x3, #:got_lo12:__libc_csu_init]
adrp x4, :got:__libc_csu_fini
ldr PTR_REG (4), [x4, #:got_lo12:__libc_csu_fini]
# else
adrp x0, __wrap_main
add x0, x0, :lo12:__wrap_main
adrp x3, __libc_csu_init
add x3, x3, :lo12:__libc_csu_init
adrp x4, __libc_csu_fini
add x4, x4, :lo12:__libc_csu_fini
# endif
#else
/* Set up the other arguments in registers */
MOVL (0, main)
MOVL (3, __libc_csu_init)
MOVL (4, __libc_csu_fini)
#endif
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini,
stack_end) */
/* Let the libc call main and exit with its return code. */
bl __libc_start_main
/* should never get here....*/
bl abort
#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:
b main
#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

View File

@ -0,0 +1,85 @@
/* Startup code for Alpha/ELF.
Copyright (C) 1993-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson <rth@tamu.edu>
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>
.text
.align 3
.globl _start
.ent _start, 0
.type _start,@function
_start:
.frame $15, 0, $15
br gp, 1f
1: ldgp gp, 0(gp)
subq sp, 16, sp
mov 0, $15
.prologue 0
/* Load address of the user's main function. */
lda a0, main
ldl a1, 16(sp) /* get argc */
lda a2, 24(sp) /* get argv */
/* Load address of our own entry points to .fini and .init. */
lda a3, __libc_csu_init
lda a4, __libc_csu_fini
/* Store address of the shared library termination function. */
mov v0, a5
/* Provide the highest stack address to the user code. */
stq sp, 0(sp)
/* Call the user's main function, and exit with its value.
But let the libc call main. */
jsr ra, __libc_start_main
/* Die very horribly if exit returns. Call_pal hlt is callable from
kernel mode only; this will result in an illegal instruction trap. */
call_pal 0
.end _start
/* For ECOFF backwards compatibility. */
weak_alias (_start, __start)
/* Define a symbol for the first piece of initialized data. */
.data
.globl __data_start
__data_start:
.weak data_start
data_start = __data_start

148
lib/libc/glibc/sysdeps/arm/start-2-33.S vendored Normal file
View File

@ -0,0 +1,148 @@
/* Startup code for ARM & ELF
Copyright (C) 1995-2020 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/>. */
/* This is the canonical entry point, usually the first thing in the text
segment.
Note that the code in the .init section has already been run.
This includes _init and _libc_init
At this entry point, most registers' values are unspecified, except:
a1 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.
sp The stack contains the arguments and environment:
0(sp) argc
4(sp) argv[0]
...
(4*argc)(sp) NULL
(4*(argc+1))(sp) envp[0]
...
NULL
*/
/* Tag_ABI_align8_preserved: This code preserves 8-byte
alignment in any callee. */
.eabi_attribute 25, 1
/* Tag_ABI_align8_needed: This code may require 8-byte alignment from
the caller. */
.eabi_attribute 24, 1
#if defined(__thumb2__)
.thumb
.syntax unified
#endif
.text
.globl _start
.type _start,#function
_start:
/* Protect against unhandled exceptions. */
.fnstart
/* Clear the frame pointer and link register since this is the outermost frame. */
mov fp, #0
mov lr, #0
/* Pop argc off the stack and save a pointer to argv */
pop { a2 }
mov a3, sp
/* Push stack limit */
push { a3 }
/* Push rtld_fini */
push { a1 }
#ifdef PIC
ldr sl, .L_GOT
adr a4, .L_GOT
add sl, sl, a4
ldr ip, .L_GOT+4 /* __libc_csu_fini */
ldr ip, [sl, ip]
push { ip } /* Push __libc_csu_fini */
ldr a4, .L_GOT+8 /* __libc_csu_init */
ldr a4, [sl, a4]
ldr a1, .L_GOT+12 /* main */
ldr a1, [sl, a1]
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
/* Let the libc call main and exit with its return code. */
bl __libc_start_main(PLT)
#else
/* Fetch address of __libc_csu_fini */
ldr ip, =__libc_csu_fini
/* Push __libc_csu_fini */
push { ip }
/* Set up the other arguments in registers */
ldr a1, =main
ldr a4, =__libc_csu_init
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
/* Let the libc call main and exit with its return code. */
bl __libc_start_main
#endif
/* should never get here....*/
bl abort
#ifdef PIC
.align 2
.L_GOT:
.word _GLOBAL_OFFSET_TABLE_ - .L_GOT
.word __libc_csu_fini(GOT)
.word __libc_csu_init(GOT)
.word main(GOT)
#endif
.cantunwind
.fnend
/* 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

152
lib/libc/glibc/sysdeps/hppa/start-2-33.S vendored Normal file
View File

@ -0,0 +1,152 @@
/* ELF startup code for HPPA.
Copyright (C) 2002-2020 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/>. */
.import main, code
.import $global$, data
.import __libc_start_main, code
.import __libc_csu_fini, code
.import __libc_csu_init, code
/* Have the linker create plabel words so we get PLABEL32
relocs and not 21/14. The use of 21/14 relocs is only
supported in the latest dynamic linker. */
#ifdef PIC
.section .data.rel.ro,"aw",@progbits
#else
.section .rodata,"a",@progbits
#endif
.align 4
.Lpmain:
.word P%main
.Lp__libc_start_main:
.word P%__libc_start_main
.Lp__libc_csu_fini:
.word P%__libc_csu_fini
.Lp__libc_csu_init:
.word P%__libc_csu_init
.text
.align 4
.globl _start
.export _start, ENTRY
.type _start,@function
_start:
/* At entry to the function we have:
r26 - Unused
r25 - argc
r24 - argv
r23 - False _dl_fini plabel address
This function is called from the lower half of RTLD_START.
The call to __libc_start_main expects:
1. r26 - Application main
2. r25 - argc
3. r24 - argv
4. r23 - __libc_csu_init
5. sp-52 - __libc_csu_fini
6. sp-56 - rtld_fini
7. sp-60 - stackend */
.proc
.callinfo
/* Clear previous-sp. */
stw %r0, -4(%sp)
/* Setup the stack and frame. */
stw %rp, -20(%sp)
ldo 64(%sp), %sp
stw %sp, -4(%sp)
stw %r19, -32(%sp)
/* argc and argv should be in 25 and 24 (2nd and 3rd argument) */
/* void (*rtld_fini) (void) (6th argument) */
stw %r23, -56(%sp)
/* Need to setup 1, 4, 5, and 7th arguments */
#ifdef PIC
/* Load $global$ address into %dp */
bl .+8, %dp
addil L'$global$-$PIC_pcrel$0+1, %dp
ldo R'$global$-$PIC_pcrel$0+5(%r1), %dp
/* load main (1st argument) */
addil LT'.Lpmain, %r19
ldw RT'.Lpmain(%r1), %r26
ldw 0(%r26),%r26
/* void (*init) (void) (4th argument) */
addil LT'.Lp__libc_csu_init, %r19
ldw RT'.Lp__libc_csu_init(%r1), %r23
ldw 0(%r23), %r23
/* void (*fini) (void) (5th argument) */
addil LT'.Lp__libc_csu_fini, %r19
ldw RT'.Lp__libc_csu_fini(%r1), %r22
ldw 0(%r22), %r22
#else
/* Load $global$ address into %dp */
ldil L%$global$, %dp
ldo R%$global$(%dp), %dp
/* load main (1st argument) */
ldil LR'.Lpmain, %r26
ldw RR'.Lpmain(%r26), %r26
/* void (*init) (void) (4th argument) */
ldil LR'.Lp__libc_csu_init, %r23
ldw RR'.Lp__libc_csu_init(%r23), %r23
/* void (*fini) (void) (5th argument) */
ldil LR'.Lp__libc_csu_fini, %r22
ldw RR'.Lp__libc_csu_fini(%r22), %r22
#endif
/* Store 5th argument */
stw %r22, -52(%sp)
/* void *stack_end (7th argument) */
stw %sp, -60(%sp)
bl __libc_start_main,%r2
nop
/* die horribly if it returned (it shouldn't) */
iitlbp %r0,(%sr0,%r0)
nop
.procend
/* 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

151
lib/libc/glibc/sysdeps/i386/start-2-33.S vendored Normal file
View File

@ -0,0 +1,151 @@
/* Startup code compliant to the ELF i386 ABI.
Copyright (C) 1995-2020 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/>. */
/* This is the canonical entry point, usually the first thing in the text
segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
point runs, most registers' values are unspecified, except for:
%edx 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.
%esp The stack contains the arguments and environment:
0(%esp) argc
4(%esp) argv[0]
...
(4*argc)(%esp) NULL
(4*(argc+1))(%esp) envp[0]
...
NULL
*/
#include <sysdep.h>
ENTRY (_start)
/* Clearing frame pointer is insufficient, use CFI. */
cfi_undefined (eip)
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
xorl %ebp, %ebp
/* Extract the arguments as encoded on the stack and set up
the arguments for `main': argc, argv. envp will be determined
later in __libc_start_main. */
popl %esi /* Pop the argument count. */
movl %esp, %ecx /* argv starts just at the current stack top.*/
/* Before pushing the arguments align the stack to a 16-byte
(SSE needs 16-byte alignment) boundary to avoid penalties from
misaligned accesses. Thanks to Edward Seidl <seidl@janed.com>
for pointing this out. */
andl $0xfffffff0, %esp
pushl %eax /* Push garbage because we allocate
28 more bytes. */
/* Provide the highest stack address to the user code (for stacks
which grow downwards). */
pushl %esp
pushl %edx /* Push address of the shared library
termination function. */
#ifdef PIC
/* Load PIC register. */
call 1f
addl $_GLOBAL_OFFSET_TABLE_, %ebx
/* Push address of our own entry points to .fini and .init. */
leal __libc_csu_fini@GOTOFF(%ebx), %eax
pushl %eax
leal __libc_csu_init@GOTOFF(%ebx), %eax
pushl %eax
pushl %ecx /* Push second argument: argv. */
pushl %esi /* Push first argument: argc. */
# ifdef SHARED
pushl main@GOT(%ebx)
# else
/* Avoid relocation in static PIE since _start is called before
it is relocated. Don't use "leal main@GOTOFF(%ebx), %eax"
since main may be in a shared object. Linker will convert
"movl main@GOT(%ebx), %eax" to "leal main@GOTOFF(%ebx), %eax"
if main is defined locally. */
movl main@GOT(%ebx), %eax
pushl %eax
# endif
/* Call the user's main function, and exit with its value.
But let the libc call main. */
call __libc_start_main@PLT
#else
/* Push address of our own entry points to .fini and .init. */
pushl $__libc_csu_fini
pushl $__libc_csu_init
pushl %ecx /* Push second argument: argv. */
pushl %esi /* Push first argument: argc. */
pushl $main
/* Call the user's main function, and exit with its value.
But let the libc call main. */
call __libc_start_main
#endif
hlt /* Crash if somehow `exit' does return. */
#ifdef PIC
1: movl (%esp), %ebx
ret
#endif
END (_start)
/* To fulfill the System V/i386 ABI we need this symbol. Yuck, it's so
meaningless since we don't support machines < 80386. */
.section .rodata
.globl _fp_hw
_fp_hw: .long 3
.size _fp_hw, 4
.type _fp_hw,@object
/* 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

118
lib/libc/glibc/sysdeps/ia64/start-2-33.S vendored Normal file
View File

@ -0,0 +1,118 @@
/* Copyright (C) 1999-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
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>
#include <asm/fpu.h>
/*
* Arguments for __libc_start_main:
* out0: main
* out1: argc
* out2: argv
* out3: init
* out4: fini
* out5: rtld_fini
* out6: stack_end
*/
.align 32
.global _start
.proc _start
.type _start,@function
_start:
.prologue
.save rp, r0
.body
.prologue
{ .mlx
alloc r2 = ar.pfs,0,0,7,0
movl r3 = FPSR_DEFAULT
}
{ .mlx
adds out2 = 16, sp /* get address of argc value */
movl gp = @gprel(0f)
;;
}
0: { .mmi
ld8 out1 = [out2], 8 /* load argc and move out2 to become argv */
mov.m r10 = ar.bsp /* fetch rbs base address */
mov r9 = ip
;;
}
{ .mii
mov ar.fpsr = r3
sub gp = r9, gp /* back-compute gp value */
adds out6 = 16, sp /* highest non-environment stack address */
;;
}
{
addl r11 = @ltoff(__libc_ia64_register_backing_store_base), gp
addl out0 = @ltoff(@fptr(main)), gp
addl out3 = @ltoff(@fptr(__libc_csu_init)), gp
;;
}
{ .mmi
ld8 r3 = [r11] /* pointer to __libc_ia64_register_backing_store_base */
ld8 out0 = [out0] /* pointer to `main' function descriptor */
addl out4 = @ltoff(@fptr(__libc_csu_fini)), gp
;;
}
{ .mmi
ld8 out3 = [out3] /* pointer to `init' function descriptor */
ld8 out4 = [out4] /* pointer to `fini' function descriptor */
nop 0
}
.body
{ .mib
st8 [r3] = r10
mov out5 = ret0 /* dynamic linker destructor */
br.call.sptk.few rp = __libc_start_main
}
{ .mib
break 0 /* break miserably if we ever return */
}
.endp _start
/* 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
.common __libc_ia64_register_backing_store_base, 8, 8

120
lib/libc/glibc/sysdeps/m68k/start-2-33.S vendored Normal file
View File

@ -0,0 +1,120 @@
/* Startup code compliant to the ELF m68k ABI.
Copyright (C) 1996-2020 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/>. */
/* This is the canonical entry point, usually the first thing in the text
segment. The SVR4/m68k ABI says that when the entry point runs,
most registers' values are unspecified, except for:
%a1 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.
%sp The stack contains the arguments and environment:
0(%sp) argc
4(%sp) argv[0]
...
(4*argc)(%sp) NULL
(4*(argc+1))(%sp) envp[0]
...
NULL
*/
#include <sysdep.h>
.text
.globl _start
.type _start,@function
_start:
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
sub.l %fp, %fp
/* Extract the arguments as encoded on the stack and set up the
arguments for `main': argc, argv. envp will be determined
later in __libc_start_main. */
move.l (%sp)+, %d0 /* Pop the argument count. */
move.l %sp, %a0 /* The argument vector starts just at the
current stack top. */
/* Provide the highest stack address to the user code (for stacks
which grow downward). */
pea (%sp)
pea (%a1) /* Push address of the shared library
termination function. */
#ifdef PIC
/* Load PIC register. */
LOAD_GOT (%a5)
/* Push the address of our own entry points to `.fini' and
`.init'. */
move.l __libc_csu_fini@GOT(%a5), -(%sp)
move.l __libc_csu_init@GOT(%a5), -(%sp)
pea (%a0) /* Push second argument: argv. */
move.l %d0, -(%sp) /* Push first argument: argc. */
move.l main@GOT(%a5), -(%sp)
/* Call the user's main function, and exit with its value. But
let the libc call main. */
jbsr __libc_start_main@PLTPC
#else
/* Push the address of our own entry points to `.fini' and
`.init'. */
pea __libc_csu_fini
pea __libc_csu_init
pea (%a0) /* Push second argument: argv. */
move.l %d0, -(%sp) /* Push first argument: argc. */
pea main
/* Call the user's main function, and exit with its value. But
let the libc call main. */
jbsr __libc_start_main
#endif
illegal /* Crash if somehow `exit' does return. */
/* 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

View File

@ -0,0 +1,84 @@
/* Copyright (C) 1995-2020 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/>. */
.text
.globl _start
.type _start,@function
_start:
/* On entry the stack contains the following args:
r1+0 - argc
r1+4 - argv[0]
...
r1+4*(argc-1) - argv[argc-1]
r1+4*argc - NULL
r1+4*argc + 4 - envp[0]
...
NULL
*/
addk r3,r0,r0
addk r5,r1,r0
1:
addik r5,r5,4
lw r4,r5,r0
bneid r4,1b
addik r3,r3,1
addik r6,r3,-1
sw r6,r1,r0
addik r7,r1,4
addik r1,r1,-24
#ifdef SHARED
/* Setup PIC. */
mfs r20,rpc
addik r20,r20,_GLOBAL_OFFSET_TABLE_+8
lwi r5,r20,main@GOT
lwi r8,r20,__libc_csu_init@GOT
lwi r9,r20,__libc_csu_fini@GOT
brid __libc_start_main@PLT
addk r10,r0,r0
#else
addik r5,r0,main
addik r8,r0,__libc_csu_init
addik r9,r0,__libc_csu_fini
brid __libc_start_main
addk r10,r0,r0
#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

185
lib/libc/glibc/sysdeps/mips/start-2-33.S vendored Normal file
View File

@ -0,0 +1,185 @@
/* Startup code compliant to the ELF Mips ABI.
Copyright (C) 1995-2020 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/>. */
#define __ASSEMBLY__ 1
#include <entry.h>
#include <sgidefs.h>
#include <sys/asm.h>
#ifndef ENTRY_POINT
#error ENTRY_POINT needs to be defined for start.S on MIPS/ELF.
#endif
/* This is the canonical entry point, usually the first thing in the text
segment. The SVR4/Mips ABI (pages 3-31, 3-32) says that when the entry
point runs, most registers' values are unspecified, except for:
v0 ($2) 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.
sp ($29) The stack contains the arguments and environment:
0(%esp) argc
4(%esp) argv[0]
...
(4*argc)(%esp) NULL
(4*(argc+1))(%esp) envp[0]
...
NULL
ra ($31) The return address register is set to zero so that programs
that search backword through stack frames recognize the last
stack frame.
*/
/* We need to call:
__libc_start_main (int (*main) (int, char **, char **), int argc,
char **argv, void (*init) (void), void (*fini) (void),
void (*rtld_fini) (void), void *stack_end)
*/
.text
.globl ENTRY_POINT
.type ENTRY_POINT,@function
#ifndef __mips16
ENTRY_POINT:
# ifdef __PIC__
SETUP_GPX($0)
SETUP_GPX64($25,$0)
# else
PTR_LA $28, _gp /* Setup GP correctly if we're non-PIC. */
move $31, $0
# endif
PTR_LA $4, main /* main */
PTR_L $5, 0($29) /* argc */
PTR_ADDIU $6, $29, PTRSIZE /* argv */
/* Allocate space on the stack for seven arguments (o32 only)
and make sure the stack is aligned to double words (8 bytes)
on o32 and quad words (16 bytes) on n32 and n64. */
and $29, -2 * SZREG
# if _MIPS_SIM == _ABIO32
PTR_SUBIU $29, 32
# endif
PTR_LA $7, __libc_csu_init /* init */
PTR_LA $8, __libc_csu_fini
# if _MIPS_SIM == _ABIO32
PTR_S $8, 16($29) /* fini */
PTR_S $2, 20($29) /* rtld_fini */
PTR_S $29, 24($29) /* stack_end */
# else
move $9, $2 /* rtld_fini */
move $10, $29 /* stack_end */
# endif
PTR_LA $25, __libc_start_main
jalr $25
hlt: b hlt /* Crash if somehow it does return. */
#elif _MIPS_SIM == _ABIO32 /* __mips16 */
/* MIPS16 entry point. */
.set mips16
ENTRY_POINT:
# ifdef __PIC__
li $3, %hi(_gp_disp)
addiu $4, $pc, %lo(_gp_disp)
sll $3, 16
addu $3, $4
move $gp, $3
# else
li $3, %hi(_gp)
sll $3, 16
addiu $3, %lo(_gp)
move $gp, $3
# endif
/* Tie end of stack frames. */
li $4, 0
move $31, $4
/* Create new SP value in $7, including alignment. */
li $4, 2 * SZREG
neg $4, $4
move $7, $sp
and $7, $4
addiu $7, -32
/* Load arguments with original SP. */
lw $5, 0($sp)
addiu $6, $sp, PTRSIZE
/* Update SP. */
move $sp, $7
/* Lay out last arguments, and call __libc_start_main(). */
# ifdef __PIC__
sw $7, 24($sp) /* stack_end */
lw $4, %got(__libc_csu_fini)($3)
lw $7, %got(__libc_csu_init)($3) /* init */
sw $4, 16($sp) /* fini */
lw $4, %got(main)($3) /* main */
lw $3, %call16(__libc_start_main)($3)
sw $2, 20($sp) /* rtld_fini */
move $25, $3
jalr $3
# else
lw $4, 1f
sw $7, 24($sp) /* stack_end */
lw $7, 2f /* init */
sw $4, 16($sp) /* fini */
lw $4, 3f /* main */
sw $2, 20($sp) /* rtld_fini */
/* Load and call __libc_start_main(). */
lw $3, 4f
jalr $3
# endif
hlt: b hlt /* Crash if somehow it does return. */
# ifndef __PIC__
.align 2
1: .word __libc_csu_fini
2: .word __libc_csu_init
3: .word main
4: .word __libc_start_main
# endif
#else /* __mips16 && _MIPS_SIM != _ABIO32 */
# error "MIPS16 support for N32/N64 not implemented"
#endif /* __mips16 */
/* 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

View File

@ -0,0 +1,95 @@
/* Startup code for programs linked with GNU libc.
Copyright (C) 1998-2020 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>
/* We do not want .eh_frame info for crt1.o since crt1.o is linked
before crtbegin.o, the file defining __EH_FRAME_BEGIN__. */
#undef cfi_startproc
#define cfi_startproc
#undef cfi_endproc
#define cfi_endproc
/* These are the various addresses we require. */
#ifdef PIC
.section ".data"
#else
.section ".rodata"
#endif
.align 2
L(start_addresses):
.long _SDA_BASE_
.long main
.long __libc_csu_init
.long __libc_csu_fini
ASM_SIZE_DIRECTIVE(L(start_addresses))
.section ".text"
ENTRY(_start)
/* Save the stack pointer, in case we're statically linked under Linux. */
mr r9,r1
/* Set up an initial stack frame, and clear the LR. */
clrrwi r1,r1,4
#ifdef PIC
SETUP_GOT_ACCESS(r13,got_label)
li r0,0
#else
li r0,0
#endif
stwu r1,-16(r1)
mtlr r0
stw r0,0(r1)
/* Set r13 to point at the 'small data area', and put the address of
start_addresses in r8. Also load the GOT pointer so that new PLT
calls work, like the one to __libc_start_main. */
#ifdef PIC
addis r30,r13,_GLOBAL_OFFSET_TABLE_-got_label@ha
addis r8,r13,L(start_addresses)-got_label@ha
addi r30,r30,_GLOBAL_OFFSET_TABLE_-got_label@l
lwzu r13, L(start_addresses)-got_label@l(r8)
#else
lis r8,L(start_addresses)@ha
lwzu r13,L(start_addresses)@l(r8)
#endif
/* and continue in libc-start, in glibc. */
b JUMPTARGET(__libc_start_main)
END(_start)
/* Define a symbol for the first piece of initialized data. */
.section ".data"
.globl __data_start
__data_start:
.long 0
weak_alias (__data_start, data_start)

View File

@ -0,0 +1,92 @@
/* Startup code for programs linked with GNU libc. PowerPC64 version.
Copyright (C) 1998-2020 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>
/* We do not want .eh_frame info for crt1.o since crt1.o is linked
before crtbegin.o, the file defining __EH_FRAME_BEGIN__. */
#undef cfi_startproc
#define cfi_startproc
#undef cfi_endproc
#define cfi_endproc
/* These are the various addresses we require. */
#ifdef PIC
.section ".data.rel.ro.local","aw"
#else
.section ".rodata"
#endif
.align 3
L(start_addresses):
.quad 0 /* was _SDA_BASE_ but not in 64-bit ABI*/
/* function descriptors so don't need JUMPTARGET */
.quad main
.quad __libc_csu_init
.quad __libc_csu_fini
ASM_SIZE_DIRECTIVE(L(start_addresses))
.section ".toc","aw"
.L01:
.tc L(start_addresses)[TC],L(start_addresses)
.section ".text"
ENTRY (_start)
/* Save the stack pointer, in case we're statically linked under Linux. */
mr r9,r1
/* Set up an initial stack frame, and clear the LR. */
clrrdi r1,r1,4
li r0,0
stdu r1,-128(r1)
mtlr r0
std r0,0(r1)
/* put the address of start_addresses in r8... **
** PPC64 ABI uses R13 for thread local, so we leave it alone */
ld r8,.L01@toc(r2)
/* and continue in libc-start, in glibc. */
b JUMPTARGET(__libc_start_main)
/* Older versions of ld need this nop to recognize that it's OK to call via a
TOC adjusting stub. */
nop
END(_start)
/* Define a symbol for the first piece of initialized data. */
.section ".data"
.globl __data_start
__data_start:
.long 0
weak_alias (__data_start, data_start)

View File

@ -0,0 +1,86 @@
/* Startup code compliant to the ELF RISC-V ABI.
Copyright (C) 1995-2020 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/>. */
#define __ASSEMBLY__ 1
#include <entry.h>
#include <sysdep.h>
#include <sys/asm.h>
/* The entry point's job is to call __libc_start_main. Per the ABI,
a0 contains the address of a function to be passed to atexit.
__libc_start_main wants this in a5. */
ENTRY (ENTRY_POINT)
/* Terminate call stack by noting ra is undefined. Use a dummy
.cfi_label to force starting the FDE. */
.cfi_label .Ldummy
cfi_undefined (ra)
call load_gp
mv a5, a0 /* rtld_fini. */
/* main may be in a shared library. */
la a0, main
REG_L a1, 0(sp) /* argc. */
addi a2, sp, SZREG /* argv. */
andi sp, sp, ALMASK /* Align stack. */
lla a3, __libc_csu_init
lla a4, __libc_csu_fini
mv a6, sp /* stack_end. */
call __libc_start_main@plt
ebreak
END (ENTRY_POINT)
/* Dynamic links need the global pointer to be initialized prior to calling
any shared library's initializers, so we use preinit_array to load it.
This doesn't cut it for static links, though, since the global pointer
needs to be initialized before calling __libc_start_main in that case.
So we redundantly initialize it at the beginning of _start. */
load_gp:
.option push
.option norelax
lla gp, __global_pointer$
.option pop
ret
.section .preinit_array,"aw"
.dc.a load_gp
/* Define a symbol for the first piece of initialized data. */
.data
.globl __data_start
__data_start:
.weak data_start
data_start = __data_start

View File

@ -0,0 +1,218 @@
/* Startup code compliant to the ELF s390 ABI.
Copyright (C) 2000-2020 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
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
4(%r15) argv[0]
...
(4*argc)(%r15) NULL
(4*(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)
/* Check if the kernel provides highgprs facility if needed by
the binary. */
lr %r6,%r15
la %r6,4(%r6) /* Skip the argument counter. */
.L11: l %r5,0(%r6) /* Skip the argument vector. */
la %r6,4(%r6)
ltr %r5,%r5
jne .L11
.L12: l %r5,0(%r6) /* Skip the environment vector. */
la %r6,4(%r6)
ltr %r5,%r5
jne .L12
/* Usually the auxiliary vector can be expected directly after
the environment variables. But we have to skip extra zeros
because the loader might have removed unsecure variables for
setuid programs. */
.L26: l %r5,0(%r6)
la %r6,4(%r6)
ltr %r5,%r5
jz .L26
ahi %r6,-4
/* Obtain the needed values from the auxiliary vector. */
lhi %r7,16 /* AT_HWCAP */
lhi %r8,3 /* AT_PHDR */
lhi %r9,5 /* AT_PHNUM */
lhi %r2,4 /* AT_PHENT */
.L13: l %r5,0(%r6)
clr %r5,%r7
jne .L15
l %r10,4(%r6) /* r10 = AT_HWCAP value. */
.L15: clr %r5,%r8
jne .L16
l %r11,4(%r6) /* r11 = AT_PHDR value. */
.L16: clr %r5,%r9
jne .L17
l %r12,4(%r6) /* r12 = AT_PHNUM value. */
.L17: clr %r5,%r2
jne .L18
l %r0,4(%r6) /* r0 = AT_PHENT value. */
.L18: ltr %r5,%r5
la %r6,8(%r6)
jnz .L13
/* Locate the ELF header by looking for the first PT_LOAD
segment with a p_offset of zero. */
lr %r4,%r11 /* Backup AT_PHDR. */
lhi %r7,1 /* PT_LOAD id */
lhi %r8,0
.L19: cl %r7,0(%r4) /* p_type == PT_LOAD? */
jne .L20
cl %r8,4(%r4) /* p_offset == 0? */
jne .L20
l %r9,8(%r4) /* r9 = PT_LOAD.p_vaddr <- ELF header address */
j .L24
.L20: alr %r4,%r0 /* r4 += AT_PHENT value */
brct %r12,.L19
j .+2 /* Trap, there must be such a phdr. */
.L24: lr %r4,%r11 /* Backup AT_PHDR. */
lhi %r2,6 /* PT_PHDR id */
.L23: cl %r2,0(%r4)
jne .L22
l %r3,8(%r4) /* r3 = PT_PHDR p_vaddr */
j .L25
.L22: alr %r4,%r0 /* r4 += AT_PHENT value */
brct %r12,.L23
j .L14 /* No PT_PHDR found - skip checking. */
.L25: slr %r11,%r3 /* AT_PHDR - PT_PHDR.p_vaddr (relocation offset)*/
alr %r9,%r11 /* PT_LOAD.p_vaddr += relocation offset */
l %r5,36(%r9) /* Load the e_flags field. */
tml %r5,1
jz .L14 /* Binary does not require highgprs facility. */
tml %r10,512 /* Check the AT_HWCAP value. */
jz 2 /* Trap if no highgprs facility available. */
.L14:
/* Setup pointer to literal pool of _start */
basr %r13,0
.L0: ahi %r13,.Llit-.L0
/* load argc and argv from stack */
la %r4,4(%r15) # get argv
l %r3,0(%r15) # get argc
/* align the stack to a double word boundary */
lhi %r0,-8
nr %r15,%r0
/* Setup a stack frame and a parameter area */
ahi %r15,-104 # make room on stack
xc 0(4,%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
*/
stm %r14,%r15,96(%r15) # store rtld_fini/stack_end to parameter area
la %r7,96(%r15)
l %r6,.L2-.Llit(%r13) # load pointer to __libc_csu_fini
l %r5,.L1-.Llit(%r13) # load pointer to __libc_csu_init
l %r2,.L3-.Llit(%r13) # load pointer to main
l %r1,.L4-.Llit(%r13) # load pointer to __libc_start_main
#ifdef PIC
l %r12,.L5-.Llit(%r13) # load .got pointer
la %r6,0(%r13,%r6)
la %r5,0(%r13,%r5)
la %r12,0(%r13,%r12)
l %r2,0(%r12,%r2)
la %r1,0(%r13,%r1)
#endif
/* ok, now branch to the libc main routine */
basr %r14,%r1
/* crash if __libc_start_main returns */
.word 0
cfi_endproc
.Llit:
#ifndef PIC
.L1: .long __libc_csu_init
.L2: .long __libc_csu_fini
.L3: .long main
.L4: .long __libc_start_main
#else
.L1: .long __libc_csu_init-.Llit
.L2: .long __libc_csu_fini-.Llit
.L3: .long main@GOT
.L4: .long __libc_start_main@plt-.Llit
.L5: .long _GLOBAL_OFFSET_TABLE_-.Llit
#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

View File

@ -0,0 +1,107 @@
/* Startup code compliant to the 64 bit S/390 ELF ABI.
Copyright (C) 2001-2020 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
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)
larl %r6,__libc_csu_fini # load pointer to __libc_csu_fini
larl %r5,__libc_csu_init # load pointer to __libc_csu_init
/* Ok, now branch to the libc main routine. */
#ifdef PIC
larl %r2,main@GOTENT # load pointer to main
lg %r2,0(%r2)
brasl %r14,__libc_start_main@plt
#else
larl %r2,main # load pointer to main
brasl %r14,__libc_start_main
#endif
/* Crash if __libc_start_main returns. */
.word 0
cfi_endproc
/* 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

111
lib/libc/glibc/sysdeps/sh/start-2-33.S vendored Normal file
View File

@ -0,0 +1,111 @@
/* Startup code for SH & ELF.
Copyright (C) 1999-2020 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/>. */
/* This is the canonical entry point, usually the first thing in the text
segment.
Note that the code in the .init section has already been run.
This includes _init and _libc_init
At this entry point, most registers' values are unspecified, except:
r4 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.
sp The stack contains the arguments and environment:
0(sp) argc
4(sp) argv[0]
...
(4*argc)(sp) NULL
(4*(argc+1))(sp) envp[0]
...
NULL
*/
.text
.globl _start
.type _start,@function
_start:
/* Clear the frame pointer since this is the outermost frame. */
mov #0, r14
/* Pop argc off the stack and save a pointer to argv */
mov.l @r15+,r5
mov r15, r6
/* Push the last arguments to main() onto the stack */
mov.l r4,@-r15
mov.l L_fini,r0
mov.l r0,@-r15
/* Set up the other arguments for main() that go in registers */
mov.l L_main,r4
mov.l L_init,r7
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini) */
/* Let the libc call main and exit with its return code. */
mov.l L_libc_start_main,r1
jsr @r1
nop
/* should never get here....*/
mov.l L_abort,r1
jsr @r1
nop
.align 2
L_main:
.long main
L_init:
.long __libc_csu_init
L_fini:
.long __libc_csu_fini
L_libc_start_main:
.long __libc_start_main
L_abort:
.long abort
/* 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
.global __fpscr_values
__fpscr_values:
.long 0
.long 0x80000

View File

@ -0,0 +1,99 @@
/* Startup code for elf32-sparc
Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
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>
.section ".text"
.align 4
.global _start
.type _start,#function
_start:
#ifdef PIC
SETUP_PIC_REG(l7)
#endif
/* Terminate the stack frame, and reserve space for functions to
drop their arguments. */
mov %g0, %fp
sub %sp, 6*4, %sp
/* Extract the arguments and environment as encoded on the stack. The
argument info starts after one register window (16 words) past the SP. */
ld [%sp+22*4], %o1
add %sp, 23*4, %o2
/* Load the addresses of the user entry points. */
#ifndef PIC
sethi %hi(main), %o0
sethi %hi(__libc_csu_init), %o3
sethi %hi(__libc_csu_fini), %o4
or %o0, %lo(main), %o0
or %o3, %lo(__libc_csu_init), %o3
or %o4, %lo(__libc_csu_fini), %o4
#else
sethi %gdop_hix22(main), %o0
sethi %gdop_hix22(__libc_csu_init), %o3
sethi %gdop_hix22(__libc_csu_fini), %o4
xor %o0, %gdop_lox10(main), %o0
xor %o3, %gdop_lox10(__libc_csu_init), %o3
xor %o4, %gdop_lox10(__libc_csu_fini), %o4
ld [%l7 + %o0], %o0, %gdop(main)
ld [%l7 + %o3], %o3, %gdop(__libc_csu_init)
ld [%l7 + %o4], %o4, %gdop(__libc_csu_fini)
#endif
/* When starting a binary via the dynamic linker, %g1 contains the
address of the shared library termination function, which will be
registered with atexit(). If we are statically linked, this will
be NULL. */
mov %g1, %o5
/* Let libc do the rest of the initialization, and call main. */
call __libc_start_main
nop
/* Die very horribly if exit returns. */
unimp
.size _start, .-_start
/* Define a symbol for the first piece of initialized data. */
.data
.globl __data_start
__data_start:
.long 0
weak_alias (__data_start, data_start)

View File

@ -0,0 +1,100 @@
/* Startup code for elf64-sparc
Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
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>
.section ".text"
.align 4
.global _start
.type _start,#function
_start:
#ifdef PIC
SETUP_PIC_REG(l7)
#endif
/* Terminate the stack frame, and reserve space for functions to
drop their arguments. */
mov %g0, %fp
sub %sp, 6*8, %sp
/* Extract the arguments and environment as encoded on the stack. The
argument info starts after one register window (16 words) past the SP,
plus the bias we added, plus the magic v9 STACK_BIAS. */
ldx [%sp+STACK_BIAS+22*8], %o1
add %sp, STACK_BIAS+23*8, %o2
/* Load the addresses of the user entry points. */
#ifndef PIC
sethi %hi(main), %o0
sethi %hi(__libc_csu_init), %o3
sethi %hi(__libc_csu_fini), %o4
or %o0, %lo(main), %o0
or %o3, %lo(__libc_csu_init), %o3
or %o4, %lo(__libc_csu_fini), %o4
#else
sethi %gdop_hix22(main), %o0
sethi %gdop_hix22(__libc_csu_init), %o3
sethi %gdop_hix22(__libc_csu_fini), %o4
xor %o0, %gdop_lox10(main), %o0
xor %o3, %gdop_lox10(__libc_csu_init), %o3
xor %o4, %gdop_lox10(__libc_csu_fini), %o4
ldx [%l7 + %o0], %o0, %gdop(main)
ldx [%l7 + %o3], %o3, %gdop(__libc_csu_init)
ldx [%l7 + %o4], %o4, %gdop(__libc_csu_fini)
#endif
/* When starting a binary via the dynamic linker, %g1 contains the
address of the shared library termination function, which will be
registered with atexit(). If we are statically linked, this will
be NULL. */
mov %g1, %o5
/* Let libc do the rest of the initialization, and call main. */
call __libc_start_main
nop
/* Die very horribly if exit returns. */
illtrap 0
.size _start, .-_start
/* Define a symbol for the first piece of initialized data. */
.data
.globl __data_start
__data_start:
.long 0
weak_alias (__data_start, data_start)

View File

@ -0,0 +1,131 @@
/* Startup code compliant to the ELF x86-64 ABI.
Copyright (C) 2001-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 2001.
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/>. */
/* This is the canonical entry point, usually the first thing in the text
segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
point runs, most registers' values are unspecified, except for:
%rdx 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.
%rsp The stack contains the arguments and environment:
0(%rsp) argc
LP_SIZE(%rsp) argv[0]
...
(LP_SIZE*argc)(%rsp) NULL
(LP_SIZE*(argc+1))(%rsp) envp[0]
...
NULL
*/
#include <sysdep.h>
ENTRY (_start)
/* Clearing frame pointer is insufficient, use CFI. */
cfi_undefined (rip)
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
xorl %ebp, %ebp
/* Extract the arguments as encoded on the stack and set up
the arguments for __libc_start_main (int (*main) (int, char **, char **),
int argc, char *argv,
void (*init) (void), void (*fini) (void),
void (*rtld_fini) (void), void *stack_end).
The arguments are passed via registers and on the stack:
main: %rdi
argc: %rsi
argv: %rdx
init: %rcx
fini: %r8
rtld_fini: %r9
stack_end: stack. */
mov %RDX_LP, %R9_LP /* Address of the shared library termination
function. */
#ifdef __ILP32__
mov (%rsp), %esi /* Simulate popping 4-byte argument count. */
add $4, %esp
#else
popq %rsi /* Pop the argument count. */
#endif
/* argv starts just at the current stack top. */
mov %RSP_LP, %RDX_LP
/* Align the stack to a 16 byte boundary to follow the ABI. */
and $~15, %RSP_LP
/* Push garbage because we push 8 more bytes. */
pushq %rax
/* Provide the highest stack address to the user code (for stacks
which grow downwards). */
pushq %rsp
#ifdef PIC
/* Pass address of our own entry points to .fini and .init. */
mov __libc_csu_fini@GOTPCREL(%rip), %R8_LP
mov __libc_csu_init@GOTPCREL(%rip), %RCX_LP
mov main@GOTPCREL(%rip), %RDI_LP
#else
/* Pass address of our own entry points to .fini and .init. */
mov $__libc_csu_fini, %R8_LP
mov $__libc_csu_init, %RCX_LP
mov $main, %RDI_LP
#endif
/* Call the user's main function, and exit with its value.
But let the libc call main. Since __libc_start_main in
libc.so is called very early, lazy binding isn't relevant
here. Use indirect branch via GOT to avoid extra branch
to PLT slot. In case of static executable, ld in binutils
2.26 or above can convert indirect branch into direct
branch. */
call *__libc_start_main@GOTPCREL(%rip)
hlt /* Crash if somehow `exit' does return. */
END (_start)
/* 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

View File

@ -182,6 +182,10 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
const target = comp.getTarget();
const target_version = target.os.version_range.linux.glibc;
const start_needs_init_fini_functions = target_version.major < 2 or (target_version.major == 2 and target_version.minor <= 33);
switch (crt_file) {
.crti_o => {
var args = std.ArrayList([]const u8).init(arena);
@ -243,7 +247,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
"-Wa,--noexecstack",
});
break :blk .{
.src_path = try start_asm_path(comp, arena, "start.S"),
.src_path = try start_asm_path(comp, arena, if (start_needs_init_fini_functions) "start-2-33.S" else "start.S"),
.extra_flags = args.items,
};
};
@ -269,7 +273,6 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
return comp.build_crt_file("Scrt1", .Obj, &[_]Compilation.CSourceFile{ start_o, abi_note_o });
},
.libc_nonshared_a => {
const target = comp.getTarget();
const s = path.sep_str;
const linux_prefix = lib_libc_glibc ++
"sysdeps" ++ s ++ "unix" ++ s ++ "sysv" ++ s ++ "linux" ++ s;
@ -309,7 +312,44 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
.{ .path = linux_prefix ++ "stat_t64_cp.c" },
};
var c_source_files: [deps.len]Compilation.CSourceFile = undefined;
var c_source_files: [deps.len + 1]Compilation.CSourceFile = undefined;
if (start_needs_init_fini_functions) {
c_source_files[0] = blk: {
var args = std.ArrayList([]const u8).init(arena);
try args.appendSlice(&[_][]const u8{
"-std=gnu11",
"-fgnu89-inline",
"-fmerge-all-constants",
"-fno-stack-protector",
"-fmath-errno",
"-I",
try lib_path(comp, arena, lib_libc_glibc ++ "csu"),
});
try add_include_dirs(comp, arena, &args);
try args.appendSlice(&[_][]const u8{
"-DSTACK_PROTECTOR_LEVEL=0",
"-fPIC",
"-fno-stack-protector",
"-fno-common",
"-ftls-model=initial-exec",
"-D_LIBC_REENTRANT",
"-include",
try lib_path(comp, arena, lib_libc_glibc ++ "include" ++ path.sep_str ++ "libc-modules.h"),
"-DMODULE_NAME=libc",
"-Wno-nonportable-include-path",
"-include",
try lib_path(comp, arena, lib_libc_glibc ++ "include" ++ path.sep_str ++ "libc-symbols.h"),
"-DPIC",
"-DLIBC_NONSHARED=1",
"-DTOP_NAMESPACE=glibc",
});
break :blk .{
.src_path = try lib_path(comp, arena, lib_libc_glibc ++ "csu" ++ path.sep_str ++ "elf-init-2-33.c"),
.extra_flags = args.items,
};
};
}
for (deps) |dep, i| {
var args = std.ArrayList([]const u8).init(arena);
@ -353,12 +393,12 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
shared_def,
"-DTOP_NAMESPACE=glibc",
});
c_source_files[i] = .{
c_source_files[i + @boolToInt(start_needs_init_fini_functions)] = .{
.src_path = try lib_path(comp, arena, dep.path),
.extra_flags = args.items,
};
}
return comp.build_crt_file("c_nonshared", .Lib, &c_source_files);
return comp.build_crt_file("c_nonshared", .Lib, c_source_files[0 .. deps.len + @boolToInt(start_needs_init_fini_functions)]);
},
}
}