1/**	$MirOS: src/libexec/ld.so/i386/ldasm.S,v 1.3 2008/10/16 14:19:02 tg Exp $ */
2/*	$OpenBSD: ldasm.S,v 1.10 2006/05/03 16:10:52 drahn Exp $ */
3
4/*
5 * Copyright (c) 2002 Dale Rahn
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31#define	__CONCAT(x,y)	x ## y
32
33#define DL_DATA_SIZE	(16*4)
34#include <sys/syscall.h>
35#include <machine/asm.h>
36
37	.text
38	.align  4
39	.globl  _dl_start
40	.type   _dl_start,@function
41_dl_start:
42	movl	%esp,%eax		# save stack pointer for _rtld
43	pushl	%ebx			# save ps_strings
44	subl	$DL_DATA_SIZE,%esp	# allocate dl_data
45	pushl	$0			# push 0 for dynamicp (unused on i386)
46	movl	%esp,%ebx
47	movl	%ebx,%edi		# save dl_data arg for dl_boot
48	pushl	%ebx			# push dl_data for dl_boot_bind
49
50	mov	%eax, %esi		# save stack for dl_boot
51
52	pushl	%eax			# load saved SP for dl_boot_bind
53
54	call	_dl_boot_bind@PLT	# _dl_boot_bind(sp,dl_data)
55
56	call	__guard_setup@PLT
57
58	pushl	%edi			# push saved dl_data
59	movl	%edi,%ebp
60	movl	(7*4)(%ebp),%eax
61	pushl	%eax			# push loff from dl_data
62
63	movl	%esi,%ebp
64	movl	$4,%eax
65	imull	0(%ebp),%eax
66	addl	$8,%eax
67	addl	%ebp,%eax
68	push	%eax			# push envp
69
70	leal	4(%ebp),%eax
71	push	%eax			# push argv
72
73	call	_dl_boot@PLT		# _dl_boot(argv,envp,loff,dl_data)
74
75	addl	$5*4,%esp		# pop args
76
77	addl	$DL_DATA_SIZE,%esp	# return dl_data
78
79	popl	%ebx			# %ebx = ps_strings - XXXDSR
80	popl	%edx			# %edx = cleanup - XXXDSR
81	popl	%ecx			# %ecx = obj_main - XXXDSR
82	jmp	*%eax
83
84
85/* copied from lib/libc/arch/i386/SYS.h - XXX */
86#define __DO_SYSCALL(x)                                 \
87	movl $__CONCAT(SYS_, x),%eax;         \
88	int $0x80
89
90
91#define DL_SYSCALL(n) DL_SYSCALL2(n,n)
92#define DL_SYSCALL2(n,c)					\
93	.section	".text"					;\
94	.align		4					;\
95	.global		__CONCAT(_dl_,n)			;\
96	.type		__CONCAT(_dl_,n)%function		;\
97__CONCAT(_dl_,n):						;\
98	__DO_SYSCALL(c)						;\
99	jb	.L_cerr						;\
100	ret
101
102DL_SYSCALL(close)
103
104	.section	".text"
105	.align		4
106	.global _dl_exit
107	.type _dl_exit,@function
108_dl_exit:
109	mov	$SYS_exit, %eax
110	int	$0x80
111	ret
112
113
114DL_SYSCALL(issetugid)
115DL_SYSCALL2(_syscall,__syscall)
116DL_SYSCALL(munmap)
117DL_SYSCALL(mprotect)
118DL_SYSCALL(open)
119DL_SYSCALL(read)
120DL_SYSCALL(write)
121DL_SYSCALL(stat)
122DL_SYSCALL(fstat)
123DL_SYSCALL(fcntl)
124DL_SYSCALL(gettimeofday)
125DL_SYSCALL2(sysctl,__sysctl)
126DL_SYSCALL(getdirentries)
127
128.L_cerr:
129	/* error: result = -errno; - handled here. */
130	neg	%eax
131	ret
132
133
134	/* _dl_sigprocmask: does not handle NULL new set */
135
136	.section	".text"
137	.align		4
138	.global _dl_sigprocmask
139	.type _dl_sigprocmask,@function
140_dl_sigprocmask:
141	movl	8(%esp), %ecx
142	movl    (%ecx),%ecx
143	movl	%ecx,8(%esp)		# to new mask arg
144	mov	$SYS_sigprocmask, %eax
145	int	$0x80
146	jb	1f		 /* error: result = -errno */
147	movl	12(%esp),%ecx		# fetch old mask requested
148	testl	%ecx,%ecx		# test if old mask requested
149	jz	2f
150	movl	%eax,(%ecx)		# store old mask
151	xorl	%eax,%eax
1522:	ret
153
1541:	/* error: result = -errno; - handled here. */
155	neg	%eax
156	ret
157
158
159	.align 4
160	.global _dl_bind_start
161	.type _dl_bind_start,@function
162_dl_bind_start:
163	pushf				# save registers
164	pushl   %eax
165	pushl   %ecx
166	pushl   %edx
167	pushl   %ebx
168	pushl   %ebp
169	pushl   %esi
170	pushl   %edi
171	pushl   %ds
172	pushl   %es
173
174	pushl   44(%esp)		# Copy of reloff
175	pushl   44(%esp)		# Copy of obj
176	call    _dl_bind@PLT		# Call the binder
177	addl    $8,%esp			# pop binder args
178	movl    %eax,44(%esp)		# Store function to be called in obj
179
180	popl    %es			# restore registers
181	popl    %ds
182	popl    %edi
183	popl    %esi
184	popl    %ebp
185	popl    %ebx
186	popl    %edx
187	popl    %ecx
188	popl    %eax
189	popf
190
191	leal    4(%esp),%esp		# Discard reloff, do not change eflags
192	ret
193