diff --git a/lib/libc/glibc/csu/elf-init-2-33.c b/lib/libc/glibc/csu/elf-init-2-33.c new file mode 100644 index 0000000000..b713c8b0fb --- /dev/null +++ b/lib/libc/glibc/csu/elf-init-2-33.c @@ -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 + . */ + +#include + + +/* 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 +} diff --git a/lib/libc/glibc/sysdeps/aarch64/start-2-33.S b/lib/libc/glibc/sysdeps/aarch64/start-2-33.S new file mode 100644 index 0000000000..d96cf57e2d --- /dev/null +++ b/lib/libc/glibc/sysdeps/aarch64/start-2-33.S @@ -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 + . */ + +#include + +/* 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 diff --git a/lib/libc/glibc/sysdeps/alpha/start-2-33.S b/lib/libc/glibc/sysdeps/alpha/start-2-33.S new file mode 100644 index 0000000000..a59898c4c0 --- /dev/null +++ b/lib/libc/glibc/sysdeps/alpha/start-2-33.S @@ -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 + + 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 + . */ + +#include + + .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 diff --git a/lib/libc/glibc/sysdeps/arm/start-2-33.S b/lib/libc/glibc/sysdeps/arm/start-2-33.S new file mode 100644 index 0000000000..2ff56179d2 --- /dev/null +++ b/lib/libc/glibc/sysdeps/arm/start-2-33.S @@ -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 + . */ + +/* 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 diff --git a/lib/libc/glibc/sysdeps/hppa/start-2-33.S b/lib/libc/glibc/sysdeps/hppa/start-2-33.S new file mode 100644 index 0000000000..c725f002dc --- /dev/null +++ b/lib/libc/glibc/sysdeps/hppa/start-2-33.S @@ -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 + . */ + + .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 diff --git a/lib/libc/glibc/sysdeps/i386/start-2-33.S b/lib/libc/glibc/sysdeps/i386/start-2-33.S new file mode 100644 index 0000000000..c57b25f055 --- /dev/null +++ b/lib/libc/glibc/sysdeps/i386/start-2-33.S @@ -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 + . */ + +/* 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 + +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 + 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 diff --git a/lib/libc/glibc/sysdeps/ia64/start-2-33.S b/lib/libc/glibc/sysdeps/ia64/start-2-33.S new file mode 100644 index 0000000000..18c8962b6e --- /dev/null +++ b/lib/libc/glibc/sysdeps/ia64/start-2-33.S @@ -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, , 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 + . */ + +#include + +#include + +/* + * 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 diff --git a/lib/libc/glibc/sysdeps/m68k/start-2-33.S b/lib/libc/glibc/sysdeps/m68k/start-2-33.S new file mode 100644 index 0000000000..f69a6502e6 --- /dev/null +++ b/lib/libc/glibc/sysdeps/m68k/start-2-33.S @@ -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 + . */ + +/* 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 + + .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 diff --git a/lib/libc/glibc/sysdeps/microblaze/start-2-33.S b/lib/libc/glibc/sysdeps/microblaze/start-2-33.S new file mode 100644 index 0000000000..55d15d6308 --- /dev/null +++ b/lib/libc/glibc/sysdeps/microblaze/start-2-33.S @@ -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 + . */ + + .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 diff --git a/lib/libc/glibc/sysdeps/mips/start-2-33.S b/lib/libc/glibc/sysdeps/mips/start-2-33.S new file mode 100644 index 0000000000..fabc8080df --- /dev/null +++ b/lib/libc/glibc/sysdeps/mips/start-2-33.S @@ -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 + . */ + +#define __ASSEMBLY__ 1 +#include +#include +#include + +#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 diff --git a/lib/libc/glibc/sysdeps/powerpc/powerpc32/start-2-33.S b/lib/libc/glibc/sysdeps/powerpc/powerpc32/start-2-33.S new file mode 100644 index 0000000000..b7b9a133a2 --- /dev/null +++ b/lib/libc/glibc/sysdeps/powerpc/powerpc32/start-2-33.S @@ -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 + . */ + +#include + +/* 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) diff --git a/lib/libc/glibc/sysdeps/powerpc/powerpc64/start-2-33.S b/lib/libc/glibc/sysdeps/powerpc/powerpc64/start-2-33.S new file mode 100644 index 0000000000..94bf771e83 --- /dev/null +++ b/lib/libc/glibc/sysdeps/powerpc/powerpc64/start-2-33.S @@ -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 + . */ + +#include + +/* 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) diff --git a/lib/libc/glibc/sysdeps/riscv/start-2-33.S b/lib/libc/glibc/sysdeps/riscv/start-2-33.S new file mode 100644 index 0000000000..09511b1ef8 --- /dev/null +++ b/lib/libc/glibc/sysdeps/riscv/start-2-33.S @@ -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 + . */ + +#define __ASSEMBLY__ 1 +#include +#include +#include + +/* 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 diff --git a/lib/libc/glibc/sysdeps/s390/s390-32/start-2-33.S b/lib/libc/glibc/sysdeps/s390/s390-32/start-2-33.S new file mode 100644 index 0000000000..af9dccfb9d --- /dev/null +++ b/lib/libc/glibc/sysdeps/s390/s390-32/start-2-33.S @@ -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 + . */ + +#include + +/* + 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 diff --git a/lib/libc/glibc/sysdeps/s390/s390-64/start-2-33.S b/lib/libc/glibc/sysdeps/s390/s390-64/start-2-33.S new file mode 100644 index 0000000000..02ed4aad51 --- /dev/null +++ b/lib/libc/glibc/sysdeps/s390/s390-64/start-2-33.S @@ -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 + . */ + +#include + +/* + 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 diff --git a/lib/libc/glibc/sysdeps/sh/start-2-33.S b/lib/libc/glibc/sysdeps/sh/start-2-33.S new file mode 100644 index 0000000000..433f67a259 --- /dev/null +++ b/lib/libc/glibc/sysdeps/sh/start-2-33.S @@ -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 + . */ + +/* 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 diff --git a/lib/libc/glibc/sysdeps/sparc/sparc32/start-2-33.S b/lib/libc/glibc/sysdeps/sparc/sparc32/start-2-33.S new file mode 100644 index 0000000000..5afc3f6e89 --- /dev/null +++ b/lib/libc/glibc/sysdeps/sparc/sparc32/start-2-33.S @@ -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 , 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 + . */ + +#include + + + .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) diff --git a/lib/libc/glibc/sysdeps/sparc/sparc64/start-2-33.S b/lib/libc/glibc/sysdeps/sparc/sparc64/start-2-33.S new file mode 100644 index 0000000000..8167a3363d --- /dev/null +++ b/lib/libc/glibc/sysdeps/sparc/sparc64/start-2-33.S @@ -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 , 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 + . */ + +#include + + + .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) diff --git a/lib/libc/glibc/sysdeps/x86_64/start-2-33.S b/lib/libc/glibc/sysdeps/x86_64/start-2-33.S new file mode 100644 index 0000000000..7477b632f7 --- /dev/null +++ b/lib/libc/glibc/sysdeps/x86_64/start-2-33.S @@ -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 , 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 + . */ + +/* 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 + +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 diff --git a/src/glibc.zig b/src/glibc.zig index 65ee88ed81..0a7ad9e332 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -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)]); }, } }