8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sgs / rtld / sparc / boot.s
blobace70a813b25ef8bbadffb0ca1ee33bdc3ea446c
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 1988 AT&T
24 * All Rights Reserved
26 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
29 #pragma ident "%Z%%M% %I% %E% SMI"
32 * Bootstrap routine for ld.so. Control arrives here either directly from
33 * exec() upon invocation of a dynamically linked program specifying ld.so
34 * as its interpreter, or from the "a.out compatibility ld.so". Entry
35 * vector at "_rt_boot" used to discriminate between the two.
37 * On entry, the stack appears as:
39 * !_______________________! high addresses
40 * ! !
41 * ! Information !
42 * ! Block !
43 * ! (size varies) !
44 * !_______________________!
45 * ! 0 word !
46 * !_______________________!
47 * ! Auxiliary !
48 * ! vector !
49 * ! 2 word entries !
50 * ! !
51 * !_______________________!
52 * ! 0 word !
53 * !_______________________!
54 * ! Environment !
55 * ! pointers !
56 * ! ... !
57 * ! (one word each) !
58 * !_______________________!
59 * ! 0 word !
60 * !_______________________!
61 * ! Argument ! low addresses
62 * ! pointers !
63 * ! Argc words !
64 * !_______________________!
65 * ! !
66 * ! Argc !
67 * !_______________________! <- %sp + 64
68 * ! !
69 * ! Window save area !
70 * !_______________________! <- %sp
72 * In the case of being invoked from the a.out compatibility ld.so, the stack
73 * has the appearance above but also several frames pushed by the compatibility
74 * routine. An "elf_boot" structure is available in %o1 on entry, which
75 * has been "pre-evaluated" to hold much of the information needed from the
76 * original stack frame -- we pass this directly into the main portion of the
77 * ld.so bootstrap.
80 #if defined(lint)
82 extern unsigned long _setup();
83 extern void atexit_fini();
85 void
86 main()
88 (void) _setup();
89 atexit_fini();
92 #else
94 #include <sys/asm_linkage.h>
95 #include <sys/param.h>
96 #include <link.h>
98 .file "boot.s"
99 .seg ".text"
100 .global _rt_boot, _setup, atexit_fini
101 .type _rt_boot, #function
102 .align 4
104 ! Entry vector
105 ! +0: normal start
106 ! +4: compatibility start
107 ! +8: alias start (frame exists)
109 _rt_boot:
110 ba,a _elf_start
111 ba,a _aout_start
112 ba,a _alias_start
114 ! Start up routines -- the aout_start will have a pointer in %o0 that we'll
115 ! want to save -- the elf can be zeroed.
117 _elf_start:
118 clr %o0 ! 0 in %o0 == ELF
119 _aout_start: ! (falls through)
121 ! Create a stack frame, perform PIC set up. If we're a "normal" start, we have
122 ! to determine a bunch of things from our "environment" and construct an ELF
123 ! boot attribute value vector. Otherwise, it's already been done and we can
124 ! skip it.
126 save %sp, -SA(MINFRAME + (EB_MAX * 8)), %sp
127 _alias_start:
128 1: ! PIC prologue
129 call 2f
130 sethi %hi(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7
132 or %l7, %lo(_GLOBAL_OFFSET_TABLE_ + (. - 1b)), %l7
134 ! If %i0 (was %o0) is non-zero, we're in compatibility and we can
135 ! skip construction of the ELF boot attribute vector.
137 addcc %i0, %g0, %o0 ! set condition codes
138 bne 1f ! if non-zero, skip setup
139 add %l7, %o7, %l7 ! finish PIC prologue
141 ! %fp points to the root of our ELF bootstrap vector, use it to construct
142 ! the vector and send it to _setup.
144 add %sp, SA(MINFRAME), %o0 ! &eb[0] == %sp + frame size
145 set EB_ARGV, %l0 ! code for this entry
146 st %l0, [%o0] ! store it
147 add %fp, 68, %l0 ! argument vector is at %fp+68
148 st %l0, [%o0 + 4] ! store that
149 ld [%fp + 64], %l1 ! get argument count
150 inc %l1 ! account for last element of 0
151 sll %l1, 2, %l1 ! multiply by 4
152 add %l0, %l1, %l0 ! and get address of first env ptr
153 st %l0, [%o0 + 12] ! store it in the vector
154 set EB_ENVP, %l1 ! code for environment base
155 st %l1, [%o0 + 8] ! store it
156 set EB_AUXV, %l1 ! get code for auxiliary vector
157 st %l1, [%o0 + 16] ! store it
159 ld [%l0], %l1 ! get an entry
160 tst %l1 ! are we at a "0" entry in environment?
161 bne 2b ! no, go back and look again
162 add %l0, 4, %l0 ! incrementing pointer in delay
163 st %l0, [%o0 + 20] ! store aux vector pointer
164 set EB_NULL, %l0 ! set up for the last pointer
165 st %l0, [%o0 + 24] ! and store it
167 ! Call _setup. Two arguments, the ELF bootstrap vector and our (unrelocated)
168 ! _DYNAMIC address. The _DYNAMIC address is located in entry 0 of the GOT
171 mov %g0, %g2 ! clear globals
172 mov %g0, %g3
173 call _setup ! call it
174 ld [%l7], %o1 ! 2nd parameter
176 ! On return, give callee the exit function in %g1, and either jump to the
177 ! target program (normal), or if return value of _setup is "0" we have
178 ! to return to the compatibility bootstrap. In either case, clear out
179 ! reserved globals.
181 ld [%l7 + atexit_fini], %g1! get function address
182 restore %o0, %g0, %l1 ! release frame
183 tst %l1 ! compatibility return?
184 be 1f ! yes,
185 mov %g0, %g4 ! but clear one last global in delay
186 jmpl %l1, %g0 ! call main program
189 retl ! compatibility return
192 .size _rt_boot, . - _rt_boot
193 #endif