1/* Startup code compliant to the ELF m68k ABI. 2 Copyright (C) 1996, 1997, 1998, 2001, 2002 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 <http://www.gnu.org/licenses/>. */ 35 36#include <features.h> 37#include "m68k_pic.S" 38 39#ifndef L_Scrt1 40/* This is the canonical entry point, usually the first thing in the text 41 segment. The SVR4/m68k ABI says that when the entry point runs, 42 most registers' values are unspecified, except for: 43 44 %a1 Contains a function pointer to be registered with `atexit'. 45 This is how the dynamic linker arranges to have DT_FINI 46 functions called for shared libraries that have been loaded 47 before this code runs. 48 49 %sp The stack contains the arguments and environment: 50 0(%sp) argc 51 4(%sp) argv[0] 52 ... 53 (4*argc)(%sp) NULL 54 (4*(argc+1))(%sp) envp[0] 55 ... 56 NULL 57 58 The uclinux conventions are different. %a1 is not defined on entry 59 and the stack is laid out as follows: 60 61 0(%sp) argc 62 4(%sp) argv 63 8(%sp) envp 64*/ 65 66 .text 67 .type _init,%function 68 .type _fini,%function 69#ifndef __UCLIBC_CTOR_DTOR__ 70 .weak _init 71 .weak _fini 72#endif 73 .globl _start 74 .type _start,@function 75_start: 76 /* Clear the frame pointer. The ABI suggests this be done, to mark 77 the outermost frame obviously. */ 78 sub.l %fp, %fp 79 80#if !defined __ARCH_USE_MMU__ && defined __PIC__ 81#ifdef UCLIBC_FORMAT_ELF 82 move.l #_GLOBAL_OFFSET_TABLE_, %a5 83#else 84 /* Set up the global pointer. The GOT is at the beginning of the 85 data segment, whose address is in %d5. */ 86 move.l %d5,%a5 87#endif 88 .equ have_current_got, 1 89#endif 90 91#ifdef __UCLIBC_FORMAT_SHARED_FLAT__ 92 CALL __shared_flat_add_library,%a1 93#endif 94 95 /* Extract the arguments as encoded on the stack and set up the 96 arguments for `main': argc, argv. envp will be determined 97 later in __libc_start_main. */ 98 move.l (%sp)+, %d0 /* Pop the argument count. */ 99#if defined(__ARCH_USE_MMU__) || defined(__UCLIBC_FORMAT_ELF__) 100 move.l %sp, %a0 /* The argument vector starts just at the 101 current stack top. */ 102#else 103 move.l (%sp)+, %a0 104#endif 105 106 /* Provide the highest stack address to the user code (for stacks 107 which grow downward). */ 108 pea (%sp) 109 110#ifndef __ARCH_USE_MMU__ 111 clr.l -(%sp) 112#else 113 pea (%a1) /* Push address of the shared library 114 termination function. */ 115#endif 116 117 /* Push the address of our own entry points to `.fini' and 118 `.init'. */ 119#if defined __UCLIBC_FORMAT_SHARED_FLAT__ 120 PEA_TEXT __shared_flat_fini,%a1 121 PEA_TEXT __shared_flat_init,%a1 122#else 123 PEA_TEXT _fini,%a1 124 PEA_TEXT _init,%a1 125#endif 126 127 pea (%a0) /* Push second argument: argv. */ 128 move.l %d0, -(%sp) /* Push first argument: argc. */ 129 130 PEA_TEXT main,%a1 131 132 /* Call the user's main function, and exit with its value. But 133 let the libc call main. */ 134 CALL __uClibc_main,%a1 135 136 illegal /* Crash if somehow `exit' does return. */ 137#else 138 .text 139 .globl lib_main 140 .hidden lib_main 141 .type lib_main,@function 142lib_main: 143 move.l %d5,%a5 144 JUMP __shared_flat_add_library,%a0 145 146 .hidden _current_shared_library_a5_offset_ 147#endif 148 149/* Define a symbol for the first piece of initialized data. */ 150 .data 151 .globl __data_start 152__data_start: 153 .long 0 154 .weak data_start 155 data_start = __data_start 156