xref: /openbsd/lib/libc/arch/alpha/SYS.h (revision 9b7c3dbb)
1 /*	$OpenBSD: SYS.h,v 1.15 2016/05/16 16:25:06 guenther Exp $	*/
2 /*	$NetBSD: SYS.h,v 1.4 1996/10/17 03:03:53 cgd Exp $	*/
3 
4 /*
5  * Copyright (c) 1994, 1995 Carnegie-Mellon University.
6  * All rights reserved.
7  *
8  * Author: Chris G. Demetriou
9  *
10  * Permission to use, copy, modify and distribute this software and
11  * its documentation is hereby granted, provided that both the copyright
12  * notice and this permission notice appear in all copies of the
13  * software, derivative works or modified versions, and any portions
14  * thereof, and that both notices appear in supporting documentation.
15  *
16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19  *
20  * Carnegie Mellon requests users of this software to return to
21  *
22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23  *  School of Computer Science
24  *  Carnegie Mellon University
25  *  Pittsburgh PA 15213-3890
26  *
27  * any improvements or extensions that they make and grant Carnegie the
28  * rights to redistribute these changes.
29  */
30 
31 #include <machine/asm.h>
32 #include <machine/pal.h>		/* for PAL_rdunique */
33 #include <sys/syscall.h>
34 
35 
36 /* offsetof(struct tib, tib_errno) - offsetof(struct tib, __tib_tcb) */
37 #define	TCB_OFFSET_ERRNO	(-12)
38 
39 /*
40  * We define a hidden alias with the prefix "_libc_" for each global symbol
41  * that may be used internally.  By referencing _libc_x instead of x, other
42  * parts of libc prevent overriding by the application and avoid unnecessary
43  * relocations.
44  */
45 #define _HIDDEN(x)		_libc_##x
46 #define _HIDDEN_ALIAS(x,y)			\
47 	STRONG_ALIAS(_HIDDEN(x),y);		\
48 	.hidden _HIDDEN(x)
49 #define _HIDDEN_FALIAS(x,y)			\
50 	_HIDDEN_ALIAS(x,y);			\
51 	.type _HIDDEN(x),@function
52 
53 /*
54  * END() uses the alpha .end pseudo-op which requires a matching .ent,
55  * so here's a short hand for just doing .size
56  */
57 #define _END(x)		.size x, . - x
58 
59 /*
60  * For functions implemented in ASM that aren't syscalls.
61  *   END_STRONG(x)	Like DEF_STRONG() in C; for standard/reserved C names
62  *   END_WEAK(x)	Like DEF_WEAK() in C; for non-ISO C names
63  */
64 #define	END_STRONG(x)	END(x); _HIDDEN_FALIAS(x,x);		\
65 			_END(_HIDDEN(x))
66 #define	END_WEAK(x)	END_STRONG(x); .weak x
67 
68 
69 #define	CALLSYS_ERROR(name)					\
70 	CALLSYS_NOERROR(name);					\
71 	beq	a3, LLABEL(name,1);				\
72 	mov	v0, t0;						\
73 	call_pal PAL_rdunique;					\
74 	stl	t0, TCB_OFFSET_ERRNO(v0);			\
75 	ldiq	v0, -1;						\
76 	RET;							\
77 LLABEL(name,1):
78 
79 #define __LEAF(p,n,e)						\
80 	LEAF(___CONCAT(p,n),e)
81 #define __END(p,n)						\
82 	END(___CONCAT(p,n));					\
83 	_HIDDEN_FALIAS(n,___CONCAT(p,n));			\
84 	_END(_HIDDEN(n))
85 
86 #define	__SYSCALL(p,name)					\
87 __LEAF(p,name,0);			/* XXX # of args? */	\
88 	CALLSYS_ERROR(name)
89 
90 #define	__SYSCALL_NOERROR(p,name)				\
91 __LEAF(p,name,0);			/* XXX # of args? */	\
92 	CALLSYS_NOERROR(name)
93 
94 
95 #define __RSYSCALL(p,name)					\
96 	__SYSCALL(p,name);					\
97 	RET;							\
98 __END(p,name)
99 
100 #define __RSYSCALL_NOERROR(p,name)				\
101 	__SYSCALL_NOERROR(p,name);				\
102 	RET;							\
103 __END(p,name)
104 
105 
106 #define	__PSEUDO(p,label,name)					\
107 __LEAF(p,label,0);			/* XXX # of args? */	\
108 	CALLSYS_ERROR(name);					\
109 	RET;							\
110 __END(p,label);
111 
112 #define	__PSEUDO_NOERROR(p,label,name)				\
113 __LEAF(p,label,0);			/* XXX # of args? */	\
114 	CALLSYS_NOERROR(name);					\
115 	RET;							\
116 __END(p,label);
117 
118 #define ALIAS(prefix,name) WEAK_ALIAS(name, ___CONCAT(prefix,name));
119 
120 /*
121  * For the thread_safe versions, we prepend _thread_sys_ to the function
122  * name so that the 'C' wrapper can go around the real name.
123  */
124 # define SYSCALL(x)		ALIAS(_thread_sys_,x) \
125 				__SYSCALL(_thread_sys_,x)
126 # define SYSCALL_NOERROR(x)	ALIAS(_thread_sys_,x) \
127 				__SYSCALL_NOERROR(_thread_sys_,x)
128 # define RSYSCALL(x)		ALIAS(_thread_sys_,x) \
129 				__RSYSCALL(_thread_sys_,x); \
130 				_END(x)
131 # define RSYSCALL_HIDDEN(x)	__RSYSCALL(_thread_sys_,x)
132 # define RSYSCALL_NOERROR(x)	ALIAS(_thread_sys_,x) \
133 				__RSYSCALL_NOERROR(_thread_sys_,x); \
134 				_END(x)
135 # define PSEUDO(x,y)		ALIAS(_thread_sys_,x) \
136 				__PSEUDO(_thread_sys_,x,y); \
137 				_END(x)
138 # define PSEUDO_NOERROR(x,y)	ALIAS(_thread_sys_,x) \
139 				__PSEUDO_NOERROR(_thread_sys_,x,y); \
140 				_END(x)
141 # define SYSLEAF_HIDDEN(x,e)	__LEAF(_thread_sys_,x,e)
142 # define SYSLEAF(x,e)		ALIAS(_thread_sys_,x) \
143 				SYSLEAF_HIDDEN(x,e)
144 # define SYSCALL_END_HIDDEN(x)	__END(_thread_sys_,x)
145 # define SYSCALL_END(x)		SYSCALL_END_HIDDEN(x); \
146 				_END(x)
147