xref: /openbsd/lib/libc/arch/alpha/SYS.h (revision 5bcead81)
1 /*	$OpenBSD: SYS.h,v 1.18 2023/12/11 22:24:15 kettenis 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 #define PINSYSCALL(sysno, label)					\
60 	.pushsection .openbsd.syscalls,"",@progbits;			\
61 	.p2align 2;							\
62 	.long label;							\
63 	.long sysno;							\
64 	.popsection;
65 
66 /*
67  * For functions implemented in ASM that aren't syscalls.
68  *   END_STRONG(x)	Like DEF_STRONG() in C; for standard/reserved C names
69  *   END_WEAK(x)	Like DEF_WEAK() in C; for non-ISO C names
70  */
71 #define	END_STRONG(x)	END(x); _HIDDEN_FALIAS(x,x);		\
72 			_END(_HIDDEN(x))
73 #define	END_WEAK(x)	END_STRONG(x); .weak x
74 
75 #define	CALLSYS_NOERROR(name)					\
76 	ldiq	v0, ___CONCAT(SYS_,name);			\
77 97:	call_pal PAL_OSF1_callsys;				\
78 	PINSYSCALL(___CONCAT(SYS_,name), 97b)
79 
80 #define	CALLSYS_ERROR(name)					\
81 	CALLSYS_NOERROR(name);					\
82 	beq	a3, LLABEL(name,1);				\
83 	mov	v0, t0;						\
84 	call_pal PAL_rdunique;					\
85 	stl	t0, TCB_OFFSET_ERRNO(v0);			\
86 	ldiq	v0, -1;						\
87 	RET;							\
88 LLABEL(name,1):
89 
90 #define __LEAF(p,n,e)						\
91 	LEAF(___CONCAT(p,n),e)
92 #define __END(p,n)						\
93 	END(___CONCAT(p,n));					\
94 	_HIDDEN_FALIAS(n,___CONCAT(p,n));			\
95 	_END(_HIDDEN(n))
96 
97 #define	__SYSCALL(p,name)					\
98 __LEAF(p,name,0);			/* XXX # of args? */	\
99 	CALLSYS_ERROR(name)
100 
101 #define	__SYSCALL_NOERROR(p,name)				\
102 __LEAF(p,name,0);			/* XXX # of args? */	\
103 	CALLSYS_NOERROR(name)
104 
105 
106 #define __RSYSCALL(p,name)					\
107 	__SYSCALL(p,name);					\
108 	RET;							\
109 __END(p,name)
110 
111 #define __RSYSCALL_NOERROR(p,name)				\
112 	__SYSCALL_NOERROR(p,name);				\
113 	RET;							\
114 __END(p,name)
115 
116 
117 #define	__PSEUDO(p,label,name)					\
118 __LEAF(p,label,0);			/* XXX # of args? */	\
119 	CALLSYS_ERROR(name);					\
120 	RET;							\
121 __END(p,label);
122 
123 #define	__PSEUDO_NOERROR(p,label,name)				\
124 __LEAF(p,label,0);			/* XXX # of args? */	\
125 	CALLSYS_NOERROR(name);					\
126 	RET;							\
127 __END(p,label);
128 
129 #define ALIAS(prefix,name) WEAK_ALIAS(name, ___CONCAT(prefix,name));
130 
131 /*
132  * For the thread_safe versions, we prepend _thread_sys_ to the function
133  * name so that the 'C' wrapper can go around the real name.
134  */
135 # define SYSCALL(x)		ALIAS(_thread_sys_,x) \
136 				__SYSCALL(_thread_sys_,x)
137 # define SYSCALL_NOERROR(x)	ALIAS(_thread_sys_,x) \
138 				__SYSCALL_NOERROR(_thread_sys_,x)
139 # define RSYSCALL(x)		ALIAS(_thread_sys_,x) \
140 				__RSYSCALL(_thread_sys_,x); \
141 				_END(x)
142 # define RSYSCALL_HIDDEN(x)	__RSYSCALL(_thread_sys_,x)
143 # define RSYSCALL_NOERROR(x)	ALIAS(_thread_sys_,x) \
144 				__RSYSCALL_NOERROR(_thread_sys_,x); \
145 				_END(x)
146 # define PSEUDO(x,y)		ALIAS(_thread_sys_,x) \
147 				__PSEUDO(_thread_sys_,x,y); \
148 				_END(x)
149 # define PSEUDO_NOERROR(x,y)	ALIAS(_thread_sys_,x) \
150 				__PSEUDO_NOERROR(_thread_sys_,x,y); \
151 				_END(x)
152 # define SYSLEAF_HIDDEN(x,e)	__LEAF(_thread_sys_,x,e)
153 # define SYSLEAF(x,e)		ALIAS(_thread_sys_,x) \
154 				SYSLEAF_HIDDEN(x,e)
155 # define SYSCALL_END_HIDDEN(x)	__END(_thread_sys_,x)
156 # define SYSCALL_END(x)		SYSCALL_END_HIDDEN(x); \
157 				_END(x)
158