_rtboot.s revision 8fd04b8338ed5093ec2d1e668fa620b7de44c177
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
.file "_rtboot.s"
/ bootstrap routine for run-time linker
/ we get control from exec which has loaded our text and
/ data into the process' address space and created the process
/ stack
/
/ on entry, the process stack looks like this:
/
/ # <- %esp
/_______________________# high addresses
/ strings #
/_______________________#
/ 0 word #
/_______________________#
/ Auxiliary #
/ entries #
/ ... #
/ (size varies) #
/_______________________#
/ 0 word #
/_______________________#
/ Environment #
/ pointers #
/ ... #
/ (one word each) #
/_______________________#
/ 0 word #
/_______________________#
/ Argument # low addresses
/ pointers #
/ Argc words #
/_______________________#
/ argc #
/_______________________# <- %ebp
#include <SYS.h>
.set EB_NULL,0
.set EB_DYNAMIC,1
.set EB_LDSO_BASE,2
.set EB_ARGV,3
.set EB_ENVP,4
.set EB_AUXV,5
.set EB_DEVZERO,6
.set EB_PAGESIZE,7
.set EB_MAX,8
.set EB_MAX_SIZE32,64
.text
.globl __rtboot
.globl __rtld
.type __rtboot,@function
.align 4
__rtboot:
movl %esp,%ebp
subl $EB_MAX_SIZE32,%esp / make room for a max sized boot vector
movl %esp,%esi / use esi as a pointer to &eb[0]
movl $EB_ARGV,0(%esi) / set up tag for argv
leal 4(%ebp),%eax / get address of argv
movl %eax,4(%esi) / put after tag
movl $EB_ENVP,8(%esi) / set up tag for envp
movl (%ebp),%eax / get # of args
addl $2,%eax / one for the zero & one for argc
leal (%ebp,%eax,4),%edi / now points past args & @ envp
movl %edi,12(%esi) / set envp
addl $-4,%edi / start loop at &env[-1]
.L00: addl $4,%edi / next
cmpl $0,(%edi) / search for 0 at end of env
jne .L00
addl $4,%edi / advance past 0
movl $EB_AUXV,16(%esi) / set up tag for auxv
movl %edi,20(%esi) / point to auxv
movl $EB_NULL,24(%esi) / set up NULL tag
call .L01 / only way to get IP into a register
.L01: popl %ebx / pop the IP we just "pushed"
leal s.EMPTY - .L01(%ebx),%eax
pushl %eax
leal s.ZERO - .L01(%ebx),%eax
pushl %eax
leal s.LDSO - .L01(%ebx),%eax
pushl %eax
movl %esp,%edi / save pointer to strings
leal f.MUNMAP - .L01(%ebx),%eax
pushl %eax
leal f.CLOSE - .L01(%ebx),%eax
pushl %eax
leal f.SYSCONFIG - .L01(%ebx),%eax
pushl %eax
leal f.FSTATAT - .L01(%ebx),%eax
pushl %eax
leal f.MMAP - .L01(%ebx),%eax
pushl %eax
leal f.OPENAT - .L01(%ebx),%eax
pushl %eax
leal f.PANIC - .L01(%ebx),%eax
pushl %eax
movl %esp,%ecx / save pointer to functions
pushl %ecx / address of functions
pushl %edi / address of strings
pushl %esi / &eb[0]
call __rtld / __rtld(&eb[0], strings, funcs)
movl %esi,%esp / restore the stack (but leaving boot vector)
jmp *%eax / transfer control to ld.so.1
.size __rtboot,.-__rtboot
.align 4
s.LDSO: .string "/usr/lib/ld.so.1"
s.ZERO: .string "/dev/zero"
s.EMPTY: .string "(null)"
s.ERROR: .string ": no (or bad) /usr/lib/ld.so.1\n"
l.ERROR:
.align 4
f.PANIC:
movl %esp,%ebp
/ Add using of argument string
pushl $l.ERROR - s.ERROR
call .L02
.L02: popl %ebx
leal s.ERROR - .L02(%ebx),%eax
pushl %eax
pushl $2
call f.WRITE
jmp f.EXIT
/ Not reached
f.OPENAT:
movl $SYS_openat,%eax
jmp __syscall
f.MMAP:
movl $SYS_mmap,%eax
jmp __syscall
f.MUNMAP:
movl $SYS_munmap,%eax
jmp __syscall
f.READ:
movl $SYS_read,%eax
jmp __syscall
f.WRITE:
movl $SYS_write,%eax
jmp __syscall
f.LSEEK:
movl $SYS_lseek,%eax
jmp __syscall
f.CLOSE:
movl $SYS_close,%eax
jmp __syscall
f.FSTATAT:
movl $SYS_fstatat,%eax
jmp __syscall
f.SYSCONFIG:
movl $SYS_sysconfig,%eax
jmp __syscall
f.EXIT:
movl $SYS_exit,%eax
/ jmp __syscall
__syscall:
int $T_SYSCALLINT
jc __err_exit
ret
__err_exit:
movl $-1,%eax
ret