zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

start.S (5443B) - Raw


      1 /* Startup code compliant to the ELF Mips ABI.
      2    Copyright (C) 1995-2025 Free Software Foundation, Inc.
      3    This file is part of the GNU C Library.
      4 
      5    The GNU C Library is free software; you can redistribute it and/or
      6    modify it under the terms of the GNU Lesser General Public
      7    License as published by the Free Software Foundation; either
      8    version 2.1 of the License, or (at your option) any later version.
      9 
     10    In addition to the permissions in the GNU Lesser General Public
     11    License, the Free Software Foundation gives you unlimited
     12    permission to link the compiled version of this file with other
     13    programs, and to distribute those programs without any restriction
     14    coming from the use of this file. (The GNU Lesser General Public
     15    License restrictions do apply in other respects; for example, they
     16    cover modification of the file, and distribution when not linked
     17    into another program.)
     18 
     19    Note that people who make modified versions of this file are not
     20    obligated to grant this special exception for their modified
     21    versions; it is their choice whether to do so. The GNU Lesser
     22    General Public License gives permission to release a modified
     23    version without this exception; this exception also makes it
     24    possible to release a modified version which carries forward this
     25    exception.
     26 
     27    The GNU C Library is distributed in the hope that it will be useful,
     28    but WITHOUT ANY WARRANTY; without even the implied warranty of
     29    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     30    Lesser General Public License for more details.
     31 
     32    You should have received a copy of the GNU Lesser General Public
     33    License along with the GNU C Library.  If not, see
     34    <https://www.gnu.org/licenses/>.  */
     35 
     36 #define __ASSEMBLY__ 1
     37 #include <entry.h>
     38 #include <sgidefs.h>
     39 #include <sys/asm.h>
     40 
     41 #ifndef ENTRY_POINT
     42 #error ENTRY_POINT needs to be defined for start.S on MIPS/ELF.
     43 #endif
     44 
     45 /* This is the canonical entry point, usually the first thing in the text
     46    segment.  The SVR4/Mips ABI (pages 3-31, 3-32) says that when the entry
     47    point runs, most registers' values are unspecified, except for:
     48 
     49    v0 ($2)	Contains a function pointer to be registered with `atexit'.
     50 		This is how the dynamic linker arranges to have DT_FINI
     51 		functions called for shared libraries that have been loaded
     52 		before this code runs.
     53 
     54    sp ($29)	The stack contains the arguments and environment:
     55 		0(%esp)			argc
     56 		4(%esp)			argv[0]
     57 		...
     58 		(4*argc)(%esp)		NULL
     59 		(4*(argc+1))(%esp)	envp[0]
     60 		...
     61 					NULL
     62    ra ($31)	The return address register is set to zero so that programs
     63 		that search backward through stack frames recognize the last
     64 		stack frame.
     65 */
     66 
     67 
     68 /* We need to call:
     69    __libc_start_main (int (*main) (int, char **, char **), int argc,
     70 		      char **argv, void (*init) (void), void (*fini) (void),
     71 		      void (*rtld_fini) (void), void *stack_end)
     72 */
     73 
     74 	.text
     75 	.globl ENTRY_POINT
     76 	.type ENTRY_POINT,@function
     77 #ifndef __mips16
     78 ENTRY_POINT:
     79 # ifdef __PIC__
     80 	SETUP_GPX($0)
     81 	SETUP_GPX64($25,$0)
     82 # else
     83 	PTR_LA $28, _gp		/* Setup GP correctly if we're non-PIC.  */
     84 	move $31, $0
     85 # endif
     86 
     87 	PTR_LA $4, main		/* main */
     88 	PTR_L $5, 0($29)		/* argc */
     89 	PTR_ADDIU $6, $29, PTRSIZE	/* argv  */
     90 
     91 	/* Allocate space on the stack for seven arguments (o32 only)
     92 	   and make sure the stack is aligned to double words (8 bytes)
     93 	   on o32 and quad words (16 bytes) on n32 and n64.  */
     94 
     95 	and $29, -2 * SZREG
     96 # if _MIPS_SIM == _ABIO32
     97 	PTR_SUBIU $29, 32
     98 # endif
     99 	move  $7, $0			/* Used to be init.  */
    100 # if _MIPS_SIM == _ABIO32
    101 	PTR_S $0, 16($29)		/* Used to be fini.  */
    102 	PTR_S $2, 20($29)		/* rtld_fini */
    103 	PTR_S $29, 24($29)		/* stack_end */
    104 # else
    105 	move $8, $0		/* Used to be fini.  */
    106 	move $9, $2		/* rtld_fini */
    107 	move $10, $29		/* stack_end */
    108 # endif
    109 	PTR_LA $25, __libc_start_main
    110 	jalr   $25
    111 hlt:	b hlt			/* Crash if somehow it does return.  */
    112 
    113 #elif _MIPS_SIM == _ABIO32 /* __mips16 */
    114 	/* MIPS16 entry point.  */
    115 	.set	mips16
    116 ENTRY_POINT:
    117 # ifdef __PIC__
    118 	li	$3, %hi(_gp_disp)
    119 	addiu	$4, $pc, %lo(_gp_disp)
    120 	sll	$3, 16
    121 	addu	$3, $4
    122 	move	$gp, $3
    123 # else
    124 	li	$3, %hi(_gp)
    125 	sll	$3, 16
    126 	addiu	$3, %lo(_gp)
    127 	move	$gp, $3
    128 # endif
    129 	/* Tie end of stack frames.  */
    130 	li	$4, 0
    131 	move	$31, $4
    132 	/* Create new SP value in $7, including alignment.  */
    133 	li	$4, 2 * SZREG
    134 	neg	$4, $4
    135 	move	$7, $sp
    136 	and	$7, $4
    137 	addiu	$7, -32
    138 	/* Load arguments with original SP.  */
    139 	lw	$5, 0($sp)
    140 	addiu	$6, $sp, PTRSIZE
    141 	/* Update SP.  */
    142 	move	$sp, $7
    143 	/* Lay out last arguments, and call __libc_start_main().  */
    144 # ifdef __PIC__
    145 	sw	$7, 24($sp)			/* stack_end */
    146 	move	$4, $0				/* Used to be ini.  */
    147 	sw	$0, 16($sp)			/* Used to be fini.  */
    148 	lw	$4, %got(main)($3)		/* main */
    149 	lw	$3, %call16(__libc_start_main)($3)
    150 	sw	$2, 20($sp)			/* rtld_fini */
    151 	move	$25, $3
    152 	jalr	$3
    153 # else
    154 	sw	$7, 24($sp)			/* stack_end */
    155 	move	$7, $0				/* Used to be init.  */
    156 	sw	$0, 16($sp)			/* Used to be fini.  */
    157 	lw	$4, 3f				/* main */
    158 	sw	$2, 20($sp)			/* rtld_fini */
    159 	/* Load and call __libc_start_main().  */
    160 	lw	$3, 4f
    161 	jalr	$3
    162 # endif
    163 hlt:	b	hlt		/* Crash if somehow it does return.  */
    164 # ifndef __PIC__
    165 	.align	2
    166 3:	.word	main
    167 4:	.word	__libc_start_main
    168 # endif
    169 
    170 #else /* __mips16 && _MIPS_SIM != _ABIO32 */
    171 # error "MIPS16 support for N32/N64 not implemented"
    172 
    173 #endif /* __mips16 */
    174 
    175 /* Define a symbol for the first piece of initialized data.  */
    176 	.data
    177 	.globl __data_start
    178 __data_start:
    179 	.long 0
    180 	.weak data_start
    181 	data_start = __data_start