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]
23 * Copyright (c) 1988 AT&T
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
44 * !_______________________!
46 * !_______________________!
51 * !_______________________!
53 * !_______________________!
58 * !_______________________!
60 * !_______________________!
61 * ! Argument ! low addresses
64 * !_______________________!
67 * !_______________________! <- %sp + 64
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
82 extern unsigned long _setup
();
83 extern void atexit_fini
();
94 #include <sys/asm_linkage.h>
95 #include <sys/param.h>
100 .global _rt_boot, _setup, atexit_fini
101 .type _rt_boot, #function
106 ! +4: compatibility start
107 ! +8: alias start
(frame exists
)
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.
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
126 save %sp, -SA(MINFRAME + (EB_MAX * 8)), %sp
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
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
181 ld [%l7
+ atexit_fini
], %g1
! get function address
182 restore
%o0
, %g0
, %l1
! release frame
183 tst
%l1
! compatibility return?
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