1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
! 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.
!
! SPARC support routines for 4.x compatibility dynamic linker.
#include <sys/asm_linkage.h> ! N.B.: although this is the 4.x
#include <sys/syscall.h> ! compatibility stuff, it actually
! runs only on the SVR4 base, and
! is compiled in an SVR4 .h environment
#define AT_FDCWD 0xffd19553
! ld.so bootstrap. Called from crt0 of a dynamically linked program with:
! %i0: version number (always 1)
! %i1: address of crt0 structure, which contains:
! +0 base address of where we are mapped
! +4 open file descriptor for /dev/zero
! +8 open file descriptor for ld.so
! +c a.out _DYNAMIC address
! +10 environment strings
! +14 break address for adb/dbx
start_rtld:
save %sp,-SA(MINFRAME),%sp ! build frame
L1:
call 1f ! get absolute address of _GOT_
nop
1:
sethi %hi(__GLOBAL_OFFSET_TABLE_ - (L1 - 1b)), %l7
L2:
or %l7, %lo(__GLOBAL_OFFSET_TABLE_ - (L1 - L2)), %l7
add %l7, %o7, %l7
mov %i0, %o0 ! pass version through
add %fp, %i1, %l0 ! get interface pointer
mov %l0, %o1 ! ptr to interface structure
ld [%l0], %l2 ! address where ld.so is mapped in
ld [%l7], %l1 ! ptr to ld.so first entry in globtable
add %l2, %l1, %o2 ! relocate ld.so _DYNAMIC
add %fp, 0xd8, %o3 ! point to arg count (is it safe?)
ld [%l7 + _rtld], %g1 ! manually fix pic reference to rtld
add %g1, %l2, %g1 ! by adding offset to GOT entry
jmpl %g1, %o7 ! go there
nop ! delay
mov 0,%o0
mov %o0,%i0
ret
restore
!
! aout_reloc_write
! Update a relocation offset, the value replaces any original
! value in the relocation offset.
!
.global _aout_reloc_write
_aout_reloc_write:
st %o1, [%o0] ! Store value in the offset
retl
iflush %o0 ! Flush instruction memory
! Special system call stubs to save system call overhead
.global _open, _mmap, _munmap, _read, _write, _lseek, _close
.global _fstat, _sysconfig, __exit
_open: ! open(path, oflags, mode) =>
mov %o2, %o3 ! openat(AT_FDCWD, path, oflag, mode)
mov %o1, %o2
mov %o0, %o1
sethi %hi(AT_FDCWD), %o0
or %o0, %lo(AT_FDCWD), %o0
ba __syscall
mov SYS_openat, %g1
_mmap:
sethi %hi(0x80000000), %g1 ! MAP_NEW
or %g1, %o3, %o3
ba __syscall
mov SYS_mmap, %g1
_munmap:
ba __syscall
mov SYS_munmap, %g1
_read:
ba __syscall
mov SYS_read, %g1
_write:
ba __syscall
mov SYS_write, %g1
_lseek:
ba __syscall
mov SYS_lseek, %g1
_close:
ba __syscall
mov SYS_close, %g1
_fstat: ! fstat(fd, statb) =>
mov %g0, %o3 ! fstatat(fd, NULL, statb, 0)
mov %o1, %o2
mov %g0, %o1
ba __syscall
mov SYS_fstatat, %g1
_sysconfig:
ba __syscall
mov SYS_sysconfig, %g1
__exit:
mov SYS_exit, %g1
__syscall:
t 0x8 ! call the system call
bcs __err_exit ! test for error
nop
retl ! return
nop
__err_exit:
retl ! return
mov -1, %o0
|