Blame sysdeps/nios2/start.S

Packit 6c4009
/* Startup code for Nios II
Packit 6c4009
   Copyright (C) 1995-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   In addition to the permissions in the GNU Lesser General Public
Packit 6c4009
   License, the Free Software Foundation gives you unlimited
Packit 6c4009
   permission to link the compiled version of this file with other
Packit 6c4009
   programs, and to distribute those programs without any restriction
Packit 6c4009
   coming from the use of this file. (The GNU Lesser General Public
Packit 6c4009
   License restrictions do apply in other respects; for example, they
Packit 6c4009
   cover modification of the file, and distribution when not linked
Packit 6c4009
   into another program.)
Packit 6c4009
Packit 6c4009
   Note that people who make modified versions of this file are not
Packit 6c4009
   obligated to grant this special exception for their modified
Packit 6c4009
   versions; it is their choice whether to do so. The GNU Lesser
Packit 6c4009
   General Public License gives permission to release a modified
Packit 6c4009
   version without this exception; this exception also makes it
Packit 6c4009
   possible to release a modified version which carries forward this
Packit 6c4009
   exception.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library.  If not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
/* This is the canonical entry point, usually the first thing in the text
Packit 6c4009
   segment.
Packit 6c4009
Packit 6c4009
	Note that the code in the .init section has already been run.
Packit 6c4009
	This includes _init and _libc_init
Packit 6c4009
Packit 6c4009
	The stack pointer, sp, will point to the argument count on the stack.
Packit 6c4009
	The initial state of the stack when a userspace process is started is:
Packit 6c4009
Packit 6c4009
	    Purpose			Start Address	Length
Packit 6c4009
	    Unspecified			High Addresses
Packit 6c4009
	    Referenced strings, etc.			Varies
Packit 6c4009
	    Unspecified
Packit 6c4009
	    Null auxilliary vector entry		4bytes
Packit 6c4009
	    Auxilliary vector entries			8bytes each
Packit 6c4009
	    NULL terminator for envp			4bytes
Packit 6c4009
	    Environment pointers	sp+8+4*argc	4bytes each
Packit 6c4009
	    NULL terminator for argv	sp+4+4*argc	4bytes
Packit 6c4009
	    Argument pointers		sp+4		4bytes each
Packit 6c4009
	    Argument count		sp		4bytes
Packit 6c4009
	    Unspecified			Low Addresses
Packit 6c4009
Packit 6c4009
	If the application should register a destructor function with atexit,
Packit 6c4009
	the pointer will be placed in r4. Otherwise r4 will be zero.
Packit 6c4009
Packit 6c4009
	The contents of all other registers are unspecified. User code should
Packit 6c4009
	set fp to zero to mark the end of the frame chain.
Packit 6c4009
Packit 6c4009
	The auxilliary vector is a series of pairs of 32-bit tag and 32-bit
Packit 6c4009
	value, terminated by an AT_NULL tag.
Packit 6c4009
*/
Packit 6c4009
Packit 6c4009
	.text
Packit 6c4009
	.globl _start
Packit 6c4009
	.type _start,%function
Packit 6c4009
_start:
Packit 6c4009
	/* Set up the global pointer.  */
Packit 6c4009
	movhi	gp, %hiadj(_gp)
Packit 6c4009
	addi	gp, gp, %lo(_gp)
Packit 6c4009
Packit 6c4009
	/* Save the stack pointer.  */
Packit 6c4009
	mov	r2, sp
Packit 6c4009
Packit 6c4009
	/* Create room on the stack for the fini, rtld_fini and stack_end args
Packit 6c4009
	   to __libc_start_main. */
Packit 6c4009
	subi	sp, sp, 12
Packit 6c4009
Packit 6c4009
	/* Push stack_end */
Packit 6c4009
	stw	r2, 8(sp)
Packit 6c4009
Packit 6c4009
	/* Push rtld_fini */
Packit 6c4009
	stw	r4, 4(sp)
Packit 6c4009
Packit 6c4009
	/* Set up the GOT pointer.  */
Packit 6c4009
	nextpc	r22
Packit 6c4009
1:	movhi	r2, %hiadj(_gp_got - 1b)
Packit 6c4009
	addi	r2, r2, %lo(_gp_got - 1b)
Packit 6c4009
	add	r22, r22, r2
Packit 6c4009
Packit 6c4009
	/* Push fini */
Packit 6c4009
	movhi	r8, %call_hiadj(__libc_csu_fini)
Packit 6c4009
	addi	r8, r8, %call_lo(__libc_csu_fini)
Packit 6c4009
	add	r8, r8, r22
Packit 6c4009
	ldw	r8, 0(r8)
Packit 6c4009
	stw	r8, 0(sp)
Packit 6c4009
Packit 6c4009
	/* r7 == init */
Packit 6c4009
	movhi	r7, %call_hiadj(__libc_csu_init)
Packit 6c4009
	addi	r7, r7, %call_lo(__libc_csu_init)
Packit 6c4009
	add	r7, r7, r22
Packit 6c4009
	ldw	r7, 0(r7)
Packit 6c4009
Packit 6c4009
	/* r6 == argv */
Packit 6c4009
	addi	r6, sp, 16
Packit 6c4009
Packit 6c4009
	/* r5 == argc */
Packit 6c4009
	ldw	r5, 12(sp)
Packit 6c4009
Packit 6c4009
	/* r4 == main */
Packit 6c4009
	movhi	r4, %call_hiadj(main)
Packit 6c4009
	addi	r4, r4, %call_lo(main)
Packit 6c4009
	add	r4, r4, r22
Packit 6c4009
	ldw	r4, 0(r4)
Packit 6c4009
Packit 6c4009
	/* fp == 0 */
Packit 6c4009
	mov	fp, zero
Packit 6c4009
Packit 6c4009
	/* __libc_start_main (main, argc, argv, init, fini, rtld_fini,
Packit 6c4009
			      stack_end) */
Packit 6c4009
Packit 6c4009
	/* Let the libc call main and exit with its return code.  */
Packit 6c4009
	movhi	r2, %call_hiadj(__libc_start_main)
Packit 6c4009
	addi	r2, r2, %call_lo(__libc_start_main)
Packit 6c4009
	add	r2, r2, r22
Packit 6c4009
	ldw	r2, 0(r2)
Packit 6c4009
	callr	r2
Packit 6c4009
Packit 6c4009
	/* should never get here....*/
Packit 6c4009
	movhi	r2, %call_hiadj(abort)
Packit 6c4009
	addi	r2, r2, %call_lo(abort)
Packit 6c4009
	add	r2, r2, r22
Packit 6c4009
	ldw	r2, 0(r2)
Packit 6c4009
	callr	r2
Packit 6c4009
Packit 6c4009
/* Define a symbol for the first piece of initialized data.  */
Packit 6c4009
	.data
Packit 6c4009
	.globl __data_start
Packit 6c4009
__data_start:
Packit 6c4009
	.long 0
Packit 6c4009
	.weak data_start
Packit 6c4009
	data_start = __data_start