xref: /openbsd-src/lib/libc/arch/i386/SYS.h (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * William Jolitz.
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  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *	$OpenBSD: SYS.h,v 1.25 2016/05/07 19:05:21 guenther Exp $
33  */
34 
35 #include <machine/asm.h>
36 #include <sys/syscall.h>
37 
38 #define TCB_OFFSET_ERRNO	16
39 
40 /*
41  * We define a hidden alias with the prefix "_libc_" for each global symbol
42  * that may be used internally.  By referencing _libc_x instead of x, other
43  * parts of libc prevent overriding by the application and avoid unnecessary
44  * relocations.
45  */
46 #define _HIDDEN(x)		_libc_##x
47 #define _HIDDEN_ALIAS(x,y)			\
48 	STRONG_ALIAS(_HIDDEN(x),y);		\
49 	.hidden _HIDDEN(x)
50 #define _HIDDEN_FALIAS(x,y)			\
51 	_HIDDEN_ALIAS(x,y);			\
52 	.type _HIDDEN(x),@function
53 
54 /*
55  * For functions implemented in ASM that aren't syscalls.
56  *   END_STRONG(x)	Like DEF_STRONG() in C; for standard/reserved C names
57  *   END_WEAK(x)	Like DEF_WEAK() in C; for non-ISO C names
58  */
59 #define	END_STRONG(x)	END(x); _HIDDEN_FALIAS(x,x); END(_HIDDEN(x))
60 #define	END_WEAK(x)	END_STRONG(x); .weak x
61 
62 
63 /*
64  * Design note:
65  *
66  * System calls entry points are really named _thread_sys_{syscall},
67  * and weakly aliased to the name {syscall}. This allows the thread
68  * library to replace system calls at link time.
69  */
70 
71 /* Use both _thread_sys_{syscall} and [weak] {syscall}. */
72 
73 #define	SYSENTRY(x)					\
74 			ENTRY(_thread_sys_##x);		\
75 			WEAK_ALIAS(x, _thread_sys_##x)
76 #define	SYSENTRY_HIDDEN(x)				\
77 			ENTRY(_thread_sys_ ## x)
78 #define	__END_HIDDEN(x)	END(_thread_sys_ ## x);			\
79 			_HIDDEN_FALIAS(x,_thread_sys_ ## x);	\
80 			END(_HIDDEN(x))
81 #define	__END(x)	__END_HIDDEN(x); END(x)
82 
83 #define	__DO_SYSCALL(x)					\
84 			movl $(SYS_ ## x),%eax;		\
85 			int $0x80
86 
87 #define SET_ERRNO()					\
88 	movl	%eax,%gs:(TCB_OFFSET_ERRNO);		\
89 	movl	$-1, %eax;				\
90 	movl	$-1, %edx	/* for lseek */
91 #define HANDLE_ERRNO()					\
92 	jnc,pt	99f;					\
93 	SET_ERRNO();					\
94 	99:
95 
96 /* perform a syscall */
97 #define	_SYSCALL_NOERROR(x,y)				\
98 		SYSENTRY(x);				\
99 			__DO_SYSCALL(y);
100 #define	_SYSCALL_HIDDEN_NOERROR(x,y)			\
101 		SYSENTRY_HIDDEN(x);			\
102 			__DO_SYSCALL(y);
103 
104 #define	SYSCALL_NOERROR(x)				\
105 		_SYSCALL_NOERROR(x,x)
106 
107 /* perform a syscall, set errno */
108 #define	_SYSCALL(x,y)					\
109 			.text;				\
110 			.align 2;			\
111 		_SYSCALL_NOERROR(x,y)			\
112 			HANDLE_ERRNO()
113 #define	_SYSCALL_HIDDEN(x,y)				\
114 			.text;				\
115 			.align 2;			\
116 		_SYSCALL_HIDDEN_NOERROR(x,y)		\
117 			HANDLE_ERRNO()
118 
119 #define	SYSCALL(x)					\
120 		_SYSCALL(x,x)
121 #define	SYSCALL_HIDDEN(x)				\
122 		_SYSCALL_HIDDEN(x,y)
123 
124 /* perform a syscall, return */
125 #define	PSEUDO_NOERROR(x,y)				\
126 		_SYSCALL_NOERROR(x,y);			\
127 			ret;				\
128 		__END(x)
129 
130 /* perform a syscall, set errno, return */
131 #define	PSEUDO(x,y)					\
132 		_SYSCALL(x,y);				\
133 			ret;				\
134 		__END(x)
135 #define	PSEUDO_HIDDEN(x,y)				\
136 		_SYSCALL_HIDDEN(x,y);			\
137 			ret;				\
138 		__END_HIDDEN(x)
139 
140 /* perform a syscall with the same name, set errno, return */
141 #define	RSYSCALL(x)					\
142 			PSEUDO(x,x);
143 #define	RSYSCALL_HIDDEN(x)				\
144 			PSEUDO_HIDDEN(x,x)
145 #define	SYSCALL_END(x)	__END(x)
146 #define	SYSCALL_END_HIDDEN(x)				\
147 			__END_HIDDEN(x)
148