1
2 #
3
4 #
5
6
7
8
9 #
10
11
12
13
14 #
15
16
17
18 include(`config-mips.m4')
19
20 .set noreorder # delay slots managed by hand
21 .set noat # no assembler macros
22 .section .text
23 .global __start
24 __start:
25 dnl li $v0, 5034 # SYS_nanosleep
26 dnl dla $a0, .timespec # rqtp
27 dnl li $a1, 0 # rmtp
28 dnl syscall # syscall
29 ld $s2, ($sp) # original stack pointer
30 DADDI3( $s0, $sp, 16) # start of load area
31 DADDI2( $sp, -16) # primary fd, secondary fd
32 li $t0, -1 # secondary fd
33 sd $t0, 8($sp) # initialize secondary fd
34 .next_action:
35 ld $s1, ($s0) # action number
36 andi $t0, $s1, 15 # t0 = action number & 15
37 beqz $t0, .open_file # open file?
38 nop # delay slot
39 DADDI2( $t0, -3) # t0 -= 3
40 beqz $t0, .rest_of_exec # jump to code
41 nop # delay slot
42 li $t1, 1
43 beq $t0, $t1, .do_mmap_anon # anonymous mmap?
44 nop # delay slot
45 .do_mmap:
46 ld $t0, 8($s0) # vm address
47 ld $t1, 16($s0) # file_offset
48 ld $t2, 24($s0) # protection
49 ld $t3, 32($s0) # length
50 ld $v0, 40($s0) # flags
51 ld $v1, ($sp) # primary fd
52 andi $s3, $s1, 16 # s1 & 16?
53 beqz $s3, .do_mmap_1 # secondary fd?
54 nop # delay slot
55 ld $v1, 8($sp) # secondary fd
56 .do_mmap_1:
57 move $a0, $t0 # syscall arg
58 move $a1, $t3 # syscall arg
59 move $a2, $t2 # syscall arg
60 move $a3, $v0 # syscall arg
61 move $a4, $v1 # syscall arg
62 move $a5, $t1 # syscall arg
63 li $v0, 5009 # SYS_mmap
64 syscall # syscall
65 bne $a3, $zero, .perror # perror?
66 nop # delay slot
67 ld $t1, 48($s0) # clear
68 dadd $t0, $a0, $a1 # t0 = end of mapping
69 dsub $t1, $t0, $t1 # t1 = t0 - clear
70 .align:
71 beq $t0, $t1, .continue # already finished
72 nop # delay slot
73 andi $t2, $t1, 7 # t1 & 7?
74 bnez $t2, .filld # start filling longs
75 nop # delay slot
76 .filld:
77 dsub $t2, $t0, $t1 # t2 = t0 - t1
78 sltiu $t2, $t2, 64 # t2 < 64?
79 bne $t2, $zero, .fillb # fill bytes
80 nop # delay slot
81 sd $zero, ($t1) # zero doubleword
82 DADDI2( $t1, 8) # next doubleword
83 sd $zero, ($t1) # zero doubleword
84 DADDI2( $t1, 8) # next doubleword
85 sd $zero, ($t1) # zero doubleword
86 DADDI2( $t1, 8) # next doubleword
87 sd $zero, ($t1) # zero doubleword
88 DADDI2( $t1, 8) # next doubleword
89 sd $zero, ($t1) # zero doubleword
90 DADDI2( $t1, 8) # next doubleword
91 sd $zero, ($t1) # zero doubleword
92 DADDI2( $t1, 8) # next doubleword
93 sd $zero, ($t1) # zero doubleword
94 DADDI2( $t1, 8) # next doubleword
95 sd $zero, ($t1) # zero doubleword
96 DADDI2( $t1, 8) # next doubleword
97 j .filld # fill either doubleword or byte
98 nop # delay slot
99 .fillb:
100 beq $t0, $t1, .continue # already finished?
101 nop # delay slot
102 sb $zero, ($t1) # clear byte
103 DADDI2( $t1, 1) # t1++
104 .continue:
105 DADDI2( $s0, 56) # s0 = next action
106 j .next_action # next action
107 nop # delay slot
108 .do_mmap_anon:
109 ld $t0, 8($s0) # vm address
110 ld $t1, 16($s0) # file_offset
111 ld $t2, 24($s0) # protection
112 ld $t3, 32($s0) # length
113 ld $v0, 40($s0) # flags
114 li $v1, -1 # fd
115 j .do_mmap_1 # do mmap
116 nop # branch delay slot
117 .open_file:
118 li $v0, 5002 # SYS_open
119 DADDI3( $a0, $s0, 8) # start of name
120 move $a1, $zero # flags = O_RDONLY
121 move $a2, $zero # mode = 0
122 syscall # syscall
123 bne $a3, $zero, .perror # perror
124 nop # delay slot
125 DADDI2( $s0, 8) # start of string
126 move $t3, $s0 # t3 = s0
127 .nextc:
128 lb $t0, ($s0) # load byte
129 DADDI2( $s0, 1) # s0++
130 li $t1, 47 # directory separator `/'
131 bne $t0, $t1, .nextc1 # is separator char?
132 nop # delay slot
133 move $t3, $s0 # t3 = char past separator
134 .nextc1:
135 bnez $t0, .nextc # next character?
136 nop # delay slot
137 DADDI2( $s0, 7) # adjust for round
138 li $t2, -8 # t2 = -8
139 and $s0, $s0, $t2 # mask for round
140 andi $t0, $s1, 16 # t1 = s1 & 16
141 move $t1, $sp # address of primary fd
142 beqz $t0, .primary # primary fd?
143 nop # delay slot
144 DADDI2( $t1, 8) # address of secondary fd
145 sd $v0, ($t1) # store fd
146 j .next_action # next action
147 nop # delay slot
148 .primary:
149 sd $v0, ($t1) # store fd
150 li $v0, 5153 # SYS_prctl
151 li $a0, 15 # PR_SET_NAME
152 move $a1, $t3 # char past separator
153 move $a2, $zero # a2
154 move $a3, $zero # a3
155 move $a4, $zero # a4
156 move $a5, $zero # a5
157 syscall # syscall
158 j .next_action # next action
159 nop # delay slot
160 .perror:
161 move $a0, $v0 # errno
162 li $v0, 5058 # SYS_exit
163 syscall # syscall
164 .rest_of_exec:
165 move $s1, $s2 # original SP
166 ld $t0, ($s1) # argc
167 dsll $t0, $t0, 3 # argc *= 8
168 DADDI2( $t0, 16) # argc += 16
169 dadd $s1, $s1, $t0 # s1 = start of envp
170 .skipenv:
171 ld $t0, ($s1) # t0 = *s1
172 DADDI2( $s1, 8) # s1++
173 bne $t0, $zero, .skipenv # skip again
174 nop # delay slot
175 dla $t3, .auxvtab # address of auxv table
176 .one_auxv:
177 ld $t0, ($s1) # t0 = auxv type
178 li $t1, 10 # t1 = 10
179 beqz $t0, .finish # is AT_IGNORE?
180 nop # delay slot
181 sltu $t1, $t0, $t1 # t1 = t0 < num offsets
182 beqz $t1, .next # next auxv
183 nop # delay slot
184 dsll $t1, $t0, 2 # t1 = t0 * 4
185 dadd $t1, $t3, $t1 # t1 = .auxvtab + t1
186 lw $t2, ($t1) # t2 = *t1
187 beqz $t2, .next # skip auxv
188 nop # delay slot
189 dadd $t2, $s0, $t2 # t2 = s0 + t2
190 ld $t2, ($t2) # t2 = *t2
191 sd $t2, 8($s1) # set auxv value
192 .next:
193 DADDI2( $s1, 16) # next auxv
194 j .one_auxv # next auxv
195 nop # delay slot
196 .finish:
197 ld $t0, 8($sp) # secondary fd
198 li $t1, -1 # t1 = -1
199 ld $s1, ($sp) # s1 = primary fd
200 li $v0, 5003 # SYS_close
201 beq $t0, $t2, .finish1 # secondary fd set?
202 nop # delay slot
203 move $a0, $t0 # secondary fd
204 syscall # syscall
205 li $v0, 5003 # SYS_close
206 .finish1:
207 move $a0, $s1 # primary fd
208 syscall # syscall
209 .jump:
210 move $v0, $zero # rtld_fini
211 ld $t0, 8($s0) # entry
212 move $sp, $s2 # restore stack pointer, delay slot
213 jr $t0 # enter
214 nop # delay slot
215
216 .auxvtab:
217 .long 0 # 0
218 .long 0 # 1
219 .long 0 # 2
220 .long 40 # 3 AT_PHDR
221 .long 24 # 4 AT_PHENT
222 .long 32 # 5 AT_PHNUM
223 .long 0 # 6
224 .long 48 # 7 AT_BASE
225 .long 0 # 8
226 .long 16 # 9 AT_ENTRY
227
228 .timespec:
229 .quad 10
230 .quad 10
231
232
233
234