initial commit
[glibc.git] / sysdeps / unix / bsd / bsd4.4 / kfreebsd / i386 / sysdep.h
1 /* Copyright (C) 1992,1993,1995-2000,2002,2003,2004
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
20
21 #ifndef _FREEBSD_I386_SYSDEP_H
22 #define _FREEBSD_I386_SYSDEP_H 1
23
24 /* There is some commonality. */
25 #include <sysdeps/unix/i386/sysdep.h>
26 /* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */
27 #include <dl-sysdep.h>
28 #include <tls.h>
29
30 #ifdef __ASSEMBLER__
31
32 /* We don't want the label for the error handle to be global when we define
33 it here. */
34 #ifdef PIC
35 # define SYSCALL_ERROR_LABEL 0f
36 #else
37 # define SYSCALL_ERROR_LABEL syscall_error
38 #endif
39
40 #undef PSEUDO
41 #define PSEUDO(name, syscall_name, args) \
42 .text; \
43 ENTRY (name) \
44 DO_CALL (syscall_name, args); \
45 jb SYSCALL_ERROR_LABEL; \
46 L(pseudo_end):
47
48 #undef PSEUDO_END
49 #define PSEUDO_END(name) \
50 SYSCALL_ERROR_HANDLER \
51 END (name)
52
53 #undef PSEUDO_NOERRNO
54 #define PSEUDO_NOERRNO(name, syscall_name, args) \
55 .text; \
56 ENTRY (name) \
57 DO_CALL (syscall_name, args)
58
59 #undef PSEUDO_END_NOERRNO
60 #define PSEUDO_END_NOERRNO(name) \
61 END (name)
62
63 #define ret_NOERRNO ret
64
65 /* The function has to return the error code. */
66 #undef PSEUDO_ERRVAL
67 #define PSEUDO_ERRVAL(name, syscall_name, args) \
68 .text; \
69 ENTRY (name) \
70 DO_CALL (syscall_name, args); \
71
72 #undef PSEUDO_END_ERRVAL
73 #define PSEUDO_END_ERRVAL(name) \
74 END (name)
75
76 #define ret_ERRVAL ret
77
78 #ifndef PIC
79 # define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
80 #else
81
82 # if RTLD_PRIVATE_ERRNO
83 # define SYSCALL_ERROR_HANDLER \
84 0:SETUP_PIC_REG(cx); \
85 addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
86 movl %eax, rtld_errno@GOTOFF(%ecx); \
87 orl $-1, %eax; \
88 jmp L(pseudo_end);
89
90 # elif defined _LIBC_REENTRANT
91
92 # if IS_IN (libc)
93 # define SYSCALL_ERROR_ERRNO __libc_errno
94 # else
95 # define SYSCALL_ERROR_ERRNO errno
96 # endif
97 # define SYSCALL_ERROR_HANDLER \
98 0:SETUP_PIC_REG (cx); \
99 addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
100 movl SYSCALL_ERROR_ERRNO@GOTNTPOFF(%ecx), %ecx; \
101 SYSCALL_ERROR_HANDLER_TLS_STORE (%eax, %ecx); \
102 orl $-1, %eax; \
103 jmp L(pseudo_end);
104 # ifndef NO_TLS_DIRECT_SEG_REFS
105 # define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff) \
106 movl src, %gs:(destoff)
107 # else
108 # define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff) \
109 addl %gs:0, destoff; \
110 movl src, (destoff)
111 # endif
112 # else
113 /* Store (%eax) into errno through the GOT. */
114 # define SYSCALL_ERROR_HANDLER \
115 0:SETUP_PIC_REG(cx); \
116 addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
117 movl errno@GOT(%ecx), %ecx; \
118 movl %eax, (%ecx); \
119 orl $-1, %eax; \
120 jmp L(pseudo_end);
121 # endif /* _LIBC_REENTRANT */
122 #endif /* PIC */
123
124 /*
125 FreeBSD expects the system call arguments on the stack,
126 syscall number is in %eax.
127 return value is in %eax + %edx
128 error is signaled via cflags.
129 all other data registers are preserved
130
131 syscall number %eax call-clobbered
132
133 The stack layout upon entering the function is:
134
135 20(%esp) Arg# 5
136 16(%esp) Arg# 4
137 12(%esp) Arg# 3
138 8(%esp) Arg# 2
139 4(%esp) Arg# 1
140 (%esp) Return address
141
142 (Of course a function with say 3 arguments does not have entries for
143 arguments 4 and 5.)
144
145 */
146
147 #undef DO_CALL
148 #define DO_CALL(syscall_name, args) \
149 movl $SYS_ify (syscall_name), %eax; \
150 int $0x80 \
151
152 #else /* !__ASSEMBLER__ */
153
154 #include <syscalls-inline.h>
155
156 /* Consistency check for position-independent code. */
157 #if defined __PIC__ && !__GNUC_PREREQ (5,0)
158 # define check_consistency() \
159 ({ int __res; \
160 __asm__ __volatile__ \
161 (LOAD_PIC_REG_STR (cx) ";" \
162 "subl %%ebx, %%ecx;" \
163 "je 1f;" \
164 "ud2;" \
165 "1:\n" \
166 : "=c" (__res)); \
167 __res; })
168 #endif
169
170 #endif /* __ASSEMBLER__ */
171
172
173 /* Pointer mangling support. */
174 #if IS_IN (rtld)
175 /* We cannot use the thread descriptor because in ld.so we use setjmp
176 earlier than the descriptor is initialized. Using a global variable
177 is too complicated here since we have no PC-relative addressing mode. */
178 #else
179 # ifdef __ASSEMBLER__
180 # define PTR_MANGLE(reg) xorl %gs:POINTER_GUARD, reg; \
181 roll $9, reg
182 # define PTR_DEMANGLE(reg) rorl $9, reg; \
183 xorl %gs:POINTER_GUARD, reg
184 # else
185 # define PTR_MANGLE(var) asm ("xorl %%gs:%c2, %0\n" \
186 "roll $9, %0" \
187 : "=r" (var) \
188 : "0" (var), \
189 "i" (offsetof (tcbhead_t, \
190 pointer_guard)))
191 # define PTR_DEMANGLE(var) asm ("rorl $9, %0\n" \
192 "xorl %%gs:%c2, %0" \
193 : "=r" (var) \
194 : "0" (var), \
195 "i" (offsetof (tcbhead_t, \
196 pointer_guard)))
197 # endif
198 #endif
199
200 #endif /* _FREEBSD_I386_SYSDEP_H */