OLD | NEW |
| (Empty) |
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |
2 /* This Source Code Form is subject to the terms of the Mozilla Public | |
3 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
5 | |
6 /* | |
7 * This file is used by not only Linux but also other glibc systems | |
8 * such as GNU/Hurd and GNU/k*BSD. | |
9 */ | |
10 | |
11 #ifndef nspr_linux_defs_h___ | |
12 #define nspr_linux_defs_h___ | |
13 | |
14 #include "prthread.h" | |
15 | |
16 /* | |
17 * Internal configuration macros | |
18 */ | |
19 | |
20 #define PR_LINKER_ARCH "linux" | |
21 #define _PR_SI_SYSNAME "LINUX" | |
22 #ifdef __powerpc64__ | |
23 #define _PR_SI_ARCHITECTURE "ppc64" | |
24 #elif defined(__powerpc__) | |
25 #define _PR_SI_ARCHITECTURE "ppc" | |
26 #elif defined(__alpha) | |
27 #define _PR_SI_ARCHITECTURE "alpha" | |
28 #elif defined(__ia64__) | |
29 #define _PR_SI_ARCHITECTURE "ia64" | |
30 #elif defined(__x86_64__) | |
31 #define _PR_SI_ARCHITECTURE "x86-64" | |
32 #elif defined(__mc68000__) | |
33 #define _PR_SI_ARCHITECTURE "m68k" | |
34 #elif defined(__sparc__) && defined(__arch64__) | |
35 #define _PR_SI_ARCHITECTURE "sparc64" | |
36 #elif defined(__sparc__) | |
37 #define _PR_SI_ARCHITECTURE "sparc" | |
38 #elif defined(__i386__) | |
39 #define _PR_SI_ARCHITECTURE "x86" | |
40 #elif defined(__mips__) | |
41 #define _PR_SI_ARCHITECTURE "mips" | |
42 #elif defined(__arm__) | |
43 #define _PR_SI_ARCHITECTURE "arm" | |
44 #elif defined(__aarch64__) | |
45 #define _PR_SI_ARCHITECTURE "aarch64" | |
46 #elif defined(__hppa__) | |
47 #define _PR_SI_ARCHITECTURE "hppa" | |
48 #elif defined(__s390x__) | |
49 #define _PR_SI_ARCHITECTURE "s390x" | |
50 #elif defined(__s390__) | |
51 #define _PR_SI_ARCHITECTURE "s390" | |
52 #elif defined(__sh__) | |
53 #define _PR_SI_ARCHITECTURE "sh" | |
54 #elif defined(__avr32__) | |
55 #define _PR_SI_ARCHITECTURE "avr32" | |
56 #elif defined(__m32r__) | |
57 #define _PR_SI_ARCHITECTURE "m32r" | |
58 #elif defined(__or1k__) | |
59 #define _PR_SI_ARCHITECTURE "or1k" | |
60 #else | |
61 #error "Unknown CPU architecture" | |
62 #endif | |
63 #define PR_DLL_SUFFIX ".so" | |
64 | |
65 #define _PR_VMBASE 0x30000000 | |
66 #define _PR_STACK_VMBASE 0x50000000 | |
67 #define _MD_DEFAULT_STACK_SIZE 65536L | |
68 #define _MD_MMAP_FLAGS MAP_PRIVATE | |
69 | |
70 #if defined(__aarch64__) || defined(__mips__) | |
71 #define _MD_MINIMUM_STACK_SIZE 0x20000 | |
72 #endif | |
73 | |
74 #undef HAVE_STACK_GROWING_UP | |
75 | |
76 /* | |
77 * Elf linux supports dl* functions | |
78 */ | |
79 #define HAVE_DLL | |
80 #define USE_DLFCN | |
81 #if defined(ANDROID) | |
82 #define NO_DLOPEN_NULL | |
83 #endif | |
84 | |
85 #if defined(__FreeBSD_kernel__) || defined(__GNU__) | |
86 #define _PR_HAVE_SOCKADDR_LEN | |
87 #endif | |
88 | |
89 #if defined(__i386__) | |
90 #define _PR_HAVE_ATOMIC_OPS | |
91 #define _MD_INIT_ATOMIC() | |
92 extern PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val); | |
93 #define _MD_ATOMIC_INCREMENT _PR_x86_AtomicIncrement | |
94 extern PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val); | |
95 #define _MD_ATOMIC_DECREMENT _PR_x86_AtomicDecrement | |
96 extern PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val); | |
97 #define _MD_ATOMIC_ADD _PR_x86_AtomicAdd | |
98 extern PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval); | |
99 #define _MD_ATOMIC_SET _PR_x86_AtomicSet | |
100 #endif | |
101 | |
102 #if defined(__ia64__) | |
103 #define _PR_HAVE_ATOMIC_OPS | |
104 #define _MD_INIT_ATOMIC() | |
105 extern PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val); | |
106 #define _MD_ATOMIC_INCREMENT _PR_ia64_AtomicIncrement | |
107 extern PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val); | |
108 #define _MD_ATOMIC_DECREMENT _PR_ia64_AtomicDecrement | |
109 extern PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val); | |
110 #define _MD_ATOMIC_ADD _PR_ia64_AtomicAdd | |
111 extern PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval); | |
112 #define _MD_ATOMIC_SET _PR_ia64_AtomicSet | |
113 #endif | |
114 | |
115 #if defined(__x86_64__) | |
116 #define _PR_HAVE_ATOMIC_OPS | |
117 #define _MD_INIT_ATOMIC() | |
118 extern PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val); | |
119 #define _MD_ATOMIC_INCREMENT _PR_x86_64_AtomicIncrement | |
120 extern PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val); | |
121 #define _MD_ATOMIC_DECREMENT _PR_x86_64_AtomicDecrement | |
122 extern PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val); | |
123 #define _MD_ATOMIC_ADD _PR_x86_64_AtomicAdd | |
124 extern PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval); | |
125 #define _MD_ATOMIC_SET _PR_x86_64_AtomicSet | |
126 #endif | |
127 | |
128 #if defined(__or1k__) | |
129 #if defined(__GNUC__) | |
130 /* Use GCC built-in functions */ | |
131 #define _PR_HAVE_ATOMIC_OPS | |
132 #define _MD_INIT_ATOMIC() | |
133 #define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1) | |
134 #define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1) | |
135 #define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i) | |
136 #define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv) | |
137 #endif | |
138 #endif | |
139 | |
140 #if defined(__powerpc__) && !defined(__powerpc64__) | |
141 #define _PR_HAVE_ATOMIC_OPS | |
142 #define _MD_INIT_ATOMIC() | |
143 extern PRInt32 _PR_ppc_AtomicIncrement(PRInt32 *val); | |
144 #define _MD_ATOMIC_INCREMENT _PR_ppc_AtomicIncrement | |
145 extern PRInt32 _PR_ppc_AtomicDecrement(PRInt32 *val); | |
146 #define _MD_ATOMIC_DECREMENT _PR_ppc_AtomicDecrement | |
147 extern PRInt32 _PR_ppc_AtomicAdd(PRInt32 *ptr, PRInt32 val); | |
148 #define _MD_ATOMIC_ADD _PR_ppc_AtomicAdd | |
149 extern PRInt32 _PR_ppc_AtomicSet(PRInt32 *val, PRInt32 newval); | |
150 #define _MD_ATOMIC_SET _PR_ppc_AtomicSet | |
151 #endif | |
152 | |
153 #if defined(__powerpc64__) | |
154 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) | |
155 /* Use GCC built-in functions */ | |
156 #define _PR_HAVE_ATOMIC_OPS | |
157 #define _MD_INIT_ATOMIC() | |
158 #define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1) | |
159 #define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1) | |
160 #define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i) | |
161 #define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv) | |
162 #endif | |
163 #endif | |
164 | |
165 #if defined(__mips__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) | |
166 /* Use GCC built-in functions */ | |
167 #define _PR_HAVE_ATOMIC_OPS | |
168 #define _MD_INIT_ATOMIC() | |
169 #define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1) | |
170 #define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1) | |
171 #define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i) | |
172 #define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv) | |
173 #endif | |
174 | |
175 #if defined(__alpha) | |
176 #define _PR_HAVE_ATOMIC_OPS | |
177 #define _MD_INIT_ATOMIC() | |
178 #define _MD_ATOMIC_ADD(ptr, i) ({ \ | |
179 PRInt32 __atomic_tmp, __atomic_ret; \ | |
180 __asm__ __volatile__( \ | |
181 "1: ldl_l %[ret], %[val] \n" \ | |
182 " addl %[ret], %[inc], %[tmp] \n" \ | |
183 " addl %[ret], %[inc], %[ret] \n" \ | |
184 " stl_c %[tmp], %[val] \n" \ | |
185 " beq %[tmp], 2f \n" \ | |
186 ".subsection 2 \n" \ | |
187 "2: br 1b \n" \ | |
188 ".previous" \ | |
189 : [ret] "=&r" (__atomic_ret), \ | |
190 [tmp] "=&r" (__atomic_tmp), \ | |
191 [val] "=m" (*ptr) \ | |
192 : [inc] "Ir" (i), "m" (*ptr)); \ | |
193 __atomic_ret; \ | |
194 }) | |
195 #define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1) | |
196 #define _MD_ATOMIC_DECREMENT(ptr) ({ \ | |
197 PRInt32 __atomic_tmp, __atomic_ret; \ | |
198 __asm__ __volatile__( \ | |
199 "1: ldl_l %[ret], %[val] \n" \ | |
200 " subl %[ret], 1, %[tmp] \n" \ | |
201 " subl %[ret], 1, %[ret] \n" \ | |
202 " stl_c %[tmp], %[val] \n" \ | |
203 " beq %[tmp], 2f \n" \ | |
204 ".subsection 2 \n" \ | |
205 "2: br 1b \n" \ | |
206 ".previous" \ | |
207 : [ret] "=&r" (__atomic_ret), \ | |
208 [tmp] "=&r" (__atomic_tmp), \ | |
209 [val] "=m" (*ptr) \ | |
210 : "m" (*ptr)); \ | |
211 __atomic_ret; \ | |
212 }) | |
213 #define _MD_ATOMIC_SET(ptr, n) ({ \ | |
214 PRInt32 __atomic_tmp, __atomic_ret; \ | |
215 __asm__ __volatile__( \ | |
216 "1: ldl_l %[ret], %[val] \n" \ | |
217 " mov %[newval], %[tmp] \n" \ | |
218 " stl_c %[tmp], %[val] \n" \ | |
219 " beq %[tmp], 2f \n" \ | |
220 ".subsection 2 \n" \ | |
221 "2: br 1b \n" \ | |
222 ".previous" \ | |
223 : [ret] "=&r" (__atomic_ret), \ | |
224 [tmp] "=&r"(__atomic_tmp), \ | |
225 [val] "=m" (*ptr) \ | |
226 : [newval] "Ir" (n), "m" (*ptr)); \ | |
227 __atomic_ret; \ | |
228 }) | |
229 #endif | |
230 | |
231 #if defined(__arm__) || defined(__aarch64__) | |
232 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) | |
233 /* Use GCC built-in functions */ | |
234 #define _PR_HAVE_ATOMIC_OPS | |
235 #define _MD_INIT_ATOMIC() | |
236 | |
237 #define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1) | |
238 #define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1) | |
239 #define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv) | |
240 #define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i) | |
241 | |
242 #elif defined(_PR_ARM_KUSER) | |
243 #define _PR_HAVE_ATOMIC_OPS | |
244 #define _MD_INIT_ATOMIC() | |
245 | |
246 /* | |
247 * The kernel provides this helper function at a fixed address with a fixed | |
248 * ABI signature, directly callable from user space. | |
249 * | |
250 * Definition: | |
251 * Atomically store newval in *ptr if *ptr is equal to oldval. | |
252 * Return zero if *ptr was changed or non-zero if no exchange happened. | |
253 */ | |
254 typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr); | |
255 #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) | |
256 | |
257 #define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1) | |
258 #define _MD_ATOMIC_DECREMENT(ptr) _MD_ATOMIC_ADD(ptr, -1) | |
259 | |
260 static inline PRInt32 _MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 n) | |
261 { | |
262 PRInt32 ov, nv; | |
263 volatile PRInt32 *vp = ptr; | |
264 | |
265 do { | |
266 ov = *vp; | |
267 nv = ov + n; | |
268 } while (__kernel_cmpxchg(ov, nv, vp)); | |
269 | |
270 return nv; | |
271 } | |
272 | |
273 static inline PRInt32 _MD_ATOMIC_SET(PRInt32 *ptr, PRInt32 nv) | |
274 { | |
275 PRInt32 ov; | |
276 volatile PRInt32 *vp = ptr; | |
277 | |
278 do { | |
279 ov = *vp; | |
280 } while (__kernel_cmpxchg(ov, nv, vp)); | |
281 | |
282 return ov; | |
283 } | |
284 #endif | |
285 #endif /* __arm__ */ | |
286 | |
287 #define USE_SETJMP | |
288 #if (defined(__GLIBC__) && __GLIBC__ >= 2) || defined(ANDROID) | |
289 #define _PR_POLL_AVAILABLE | |
290 #endif | |
291 #undef _PR_USE_POLL | |
292 #define _PR_STAT_HAS_ONLY_ST_ATIME | |
293 #if defined(__alpha) || defined(__ia64__) | |
294 #define _PR_HAVE_LARGE_OFF_T | |
295 #elif (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) \ | |
296 || defined(ANDROID) | |
297 #define _PR_HAVE_OFF64_T | |
298 #else | |
299 #define _PR_NO_LARGE_FILES | |
300 #endif | |
301 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) \ | |
302 || defined(ANDROID) | |
303 #define _PR_INET6 | |
304 #define _PR_HAVE_INET_NTOP | |
305 #define _PR_HAVE_GETHOSTBYNAME2 | |
306 #define _PR_HAVE_GETADDRINFO | |
307 #define _PR_INET6_PROBE | |
308 #endif | |
309 #ifndef ANDROID | |
310 #define _PR_HAVE_SYSV_SEMAPHORES | |
311 #define PR_HAVE_SYSV_NAMED_SHARED_MEMORY | |
312 #endif | |
313 /* Android has gethostbyname_r but not gethostbyaddr_r or gethostbyname2_r. */ | |
314 #if (__GLIBC__ >= 2) && defined(_PR_PTHREADS) | |
315 #define _PR_HAVE_GETHOST_R | |
316 #define _PR_HAVE_GETHOST_R_INT | |
317 #endif | |
318 | |
319 #ifdef _PR_PTHREADS | |
320 | |
321 extern void _MD_CleanupBeforeExit(void); | |
322 #define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit | |
323 | |
324 #else /* ! _PR_PTHREADS */ | |
325 | |
326 #include <setjmp.h> | |
327 | |
328 #define PR_CONTEXT_TYPE sigjmp_buf | |
329 | |
330 #define CONTEXT(_th) ((_th)->md.context) | |
331 | |
332 #ifdef __powerpc__ | |
333 /* | |
334 * PowerPC based MkLinux | |
335 * | |
336 * On the PowerPC, the new style jmp_buf isn't used until glibc | |
337 * 2.1. | |
338 */ | |
339 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) | |
340 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_GPR1] | |
341 #else | |
342 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__misc[0] | |
343 #endif /* glibc 2.1 or later */ | |
344 #define _MD_SET_FP(_t, val) | |
345 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
346 #define _MD_GET_FP_PTR(_t) ((void *) 0) | |
347 /* aix = 64, macos = 70 */ | |
348 #define PR_NUM_GCREGS 64 | |
349 | |
350 #elif defined(__alpha) | |
351 /* Alpha based Linux */ | |
352 | |
353 #if defined(__GLIBC__) && __GLIBC__ >= 2 | |
354 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP] | |
355 #define _MD_SET_FP(_t, val) | |
356 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
357 #define _MD_GET_FP_PTR(_t) ((void *) 0) | |
358 #define _MD_SP_TYPE long int | |
359 #else | |
360 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp | |
361 #define _MD_SET_FP(_t, val) | |
362 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
363 #define _MD_GET_FP_PTR(_t) ((void *) 0) | |
364 #define _MD_SP_TYPE __ptr_t | |
365 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ | |
366 | |
367 /* XXX not sure if this is correct, or maybe it should be 17? */ | |
368 #define PR_NUM_GCREGS 9 | |
369 | |
370 #elif defined(__ia64__) | |
371 | |
372 #define _MD_GET_SP(_t) ((long *)((_t)->md.context[0].__jmpbuf)[0]) | |
373 #define _MD_SET_FP(_t, val) | |
374 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
375 #define _MD_GET_FP_PTR(_t) ((void *) 0) | |
376 #define _MD_SP_TYPE long int | |
377 | |
378 #define PR_NUM_GCREGS _JBLEN | |
379 | |
380 #elif defined(__mc68000__) | |
381 /* m68k based Linux */ | |
382 | |
383 /* | |
384 * On the m68k, glibc still uses the old style sigjmp_buf, even | |
385 * in glibc 2.0.7. | |
386 */ | |
387 #if defined(__GLIBC__) && __GLIBC__ >= 2 | |
388 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp | |
389 #define _MD_SET_FP(_t, val) | |
390 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
391 #define _MD_GET_FP_PTR(_t) ((void *) 0) | |
392 #define _MD_SP_TYPE int | |
393 #else | |
394 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp | |
395 #define _MD_SET_FP(_t, val) | |
396 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
397 #define _MD_GET_FP_PTR(_t) ((void *) 0) | |
398 #define _MD_SP_TYPE __ptr_t | |
399 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ | |
400 | |
401 /* XXX not sure if this is correct, or maybe it should be 17? */ | |
402 #define PR_NUM_GCREGS 9 | |
403 | |
404 #elif defined(__sparc__) | |
405 /* Sparc */ | |
406 #if defined(__GLIBC__) && __GLIBC__ >= 2 | |
407 /* | |
408 * You need glibc2-2.0.7-25 or later. The libraries that came with | |
409 * Red Hat 5.1 are not new enough, but they are in 5.2. | |
410 */ | |
411 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP] | |
412 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_FP] = val) | |
413 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
414 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_FP]) | |
415 #define _MD_SP_TYPE int | |
416 #else | |
417 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__fp | |
418 #define _MD_SET_FP(_t, val) | |
419 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
420 #define _MD_GET_FP_PTR(_t) ((void *) 0) | |
421 #define _MD_SP_TYPE __ptr_t | |
422 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ | |
423 | |
424 #elif defined(__i386__) | |
425 /* Intel based Linux */ | |
426 #if defined(__GLIBC__) && __GLIBC__ >= 2 | |
427 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP] | |
428 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_BP] = val) | |
429 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
430 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_BP]) | |
431 #define _MD_SP_TYPE int | |
432 #else | |
433 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp | |
434 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__bp = val) | |
435 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
436 #define _MD_GET_FP_PTR(_t) &((_t)->md.context[0].__jmpbuf[0].__bp) | |
437 #define _MD_SP_TYPE __ptr_t | |
438 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ | |
439 #define PR_NUM_GCREGS 6 | |
440 | |
441 #elif defined(__mips__) | |
442 /* Linux/MIPS */ | |
443 #if defined(__GLIBC__) && __GLIBC__ >= 2 | |
444 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp | |
445 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__fp = (val)) | |
446 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
447 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[0].__fp) | |
448 #define _MD_SP_TYPE __ptr_t | |
449 #else | |
450 #error "Linux/MIPS pre-glibc2 not supported yet" | |
451 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ | |
452 | |
453 #elif defined(__arm__) | |
454 /* ARM/Linux */ | |
455 #if defined(__GLIBC__) && __GLIBC__ >= 2 | |
456 #ifdef __ARM_EABI__ | |
457 /* EABI */ | |
458 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[8] | |
459 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[7] = (val)) | |
460 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
461 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[7]) | |
462 #define _MD_SP_TYPE __ptr_t | |
463 #else /* __ARM_EABI__ */ | |
464 /* old ABI */ | |
465 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[20] | |
466 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[19] = (val)) | |
467 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
468 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[19]) | |
469 #define _MD_SP_TYPE __ptr_t | |
470 #endif /* __ARM_EABI__ */ | |
471 #else | |
472 #error "ARM/Linux pre-glibc2 not supported yet" | |
473 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ | |
474 | |
475 #elif defined(__sh__) | |
476 /* SH/Linux */ | |
477 #if defined(__GLIBC__) && __GLIBC__ >= 2 | |
478 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[7] | |
479 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[6] = (val)) | |
480 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
481 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[6]) | |
482 #define _MD_SP_TYPE __ptr_t | |
483 #else | |
484 #error "SH/Linux pre-glibc2 not supported yet" | |
485 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ | |
486 | |
487 #elif defined(__m32r__) | |
488 /* Linux/M32R */ | |
489 #if defined(__GLIBC__) && __GLIBC__ >= 2 | |
490 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__regs[JB_SP] | |
491 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__regs[JB_FP] = (va
l)) | |
492 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t)) | |
493 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[0].__regs[JB_FP]) | |
494 #define _MD_SP_TYPE __ptr_t | |
495 #else | |
496 #error "Linux/M32R pre-glibc2 not supported yet" | |
497 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ | |
498 | |
499 #else | |
500 | |
501 #error "Unknown CPU architecture" | |
502 | |
503 #endif /*__powerpc__*/ | |
504 | |
505 /* | |
506 ** Initialize a thread context to run "_main()" when started | |
507 */ | |
508 #ifdef __powerpc__ | |
509 | |
510 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ | |
511 { \ | |
512 *status = PR_TRUE; \ | |
513 if (sigsetjmp(CONTEXT(_thread), 1)) { \ | |
514 _main(); \ | |
515 } \ | |
516 _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 128); \ | |
517 _thread->md.sp = _MD_GET_SP_PTR(_thread); \ | |
518 _thread->md.fp = _MD_GET_FP_PTR(_thread); \ | |
519 _MD_SET_FP(_thread, 0); \ | |
520 } | |
521 | |
522 #elif defined(__mips__) | |
523 | |
524 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ | |
525 { \ | |
526 *status = PR_TRUE; \ | |
527 (void) sigsetjmp(CONTEXT(_thread), 1); \ | |
528 _thread->md.context[0].__jmpbuf[0].__pc = (__ptr_t) _main; \ | |
529 _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \ | |
530 _thread->md.sp = _MD_GET_SP_PTR(_thread); \ | |
531 _thread->md.fp = _MD_GET_FP_PTR(_thread); \ | |
532 _MD_SET_FP(_thread, 0); \ | |
533 } | |
534 | |
535 #else | |
536 | |
537 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ | |
538 { \ | |
539 *status = PR_TRUE; \ | |
540 if (sigsetjmp(CONTEXT(_thread), 1)) { \ | |
541 _main(); \ | |
542 } \ | |
543 _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \ | |
544 _thread->md.sp = _MD_GET_SP_PTR(_thread); \ | |
545 _thread->md.fp = _MD_GET_FP_PTR(_thread); \ | |
546 _MD_SET_FP(_thread, 0); \ | |
547 } | |
548 | |
549 #endif /*__powerpc__*/ | |
550 | |
551 #define _MD_SWITCH_CONTEXT(_thread) \ | |
552 if (!sigsetjmp(CONTEXT(_thread), 1)) { \ | |
553 (_thread)->md.errcode = errno; \ | |
554 _PR_Schedule(); \ | |
555 } | |
556 | |
557 /* | |
558 ** Restore a thread context, saved by _MD_SWITCH_CONTEXT | |
559 */ | |
560 #define _MD_RESTORE_CONTEXT(_thread) \ | |
561 { \ | |
562 errno = (_thread)->md.errcode; \ | |
563 _MD_SET_CURRENT_THREAD(_thread); \ | |
564 siglongjmp(CONTEXT(_thread), 1); \ | |
565 } | |
566 | |
567 /* Machine-dependent (MD) data structures */ | |
568 | |
569 struct _MDThread { | |
570 PR_CONTEXT_TYPE context; | |
571 void *sp; | |
572 void *fp; | |
573 int id; | |
574 int errcode; | |
575 }; | |
576 | |
577 struct _MDThreadStack { | |
578 PRInt8 notused; | |
579 }; | |
580 | |
581 struct _MDLock { | |
582 PRInt8 notused; | |
583 }; | |
584 | |
585 struct _MDSemaphore { | |
586 PRInt8 notused; | |
587 }; | |
588 | |
589 struct _MDCVar { | |
590 PRInt8 notused; | |
591 }; | |
592 | |
593 struct _MDSegment { | |
594 PRInt8 notused; | |
595 }; | |
596 | |
597 /* | |
598 * md-specific cpu structure field | |
599 */ | |
600 #include <sys/time.h> /* for FD_SETSIZE */ | |
601 #define _PR_MD_MAX_OSFD FD_SETSIZE | |
602 | |
603 struct _MDCPU_Unix { | |
604 PRCList ioQ; | |
605 PRUint32 ioq_timeout; | |
606 PRInt32 ioq_max_osfd; | |
607 PRInt32 ioq_osfd_cnt; | |
608 #ifndef _PR_USE_POLL | |
609 fd_set fd_read_set, fd_write_set, fd_exception_set; | |
610 PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD], | |
611 fd_exception_cnt[_PR_MD_MAX_OSFD]; | |
612 #else | |
613 struct pollfd *ioq_pollfds; | |
614 int ioq_pollfds_size; | |
615 #endif /* _PR_USE_POLL */ | |
616 }; | |
617 | |
618 #define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ) | |
619 #define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu)) | |
620 #define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set) | |
621 #define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt) | |
622 #define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set) | |
623 #define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt) | |
624 #define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set) | |
625 #define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt) | |
626 #define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout) | |
627 #define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd) | |
628 #define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt) | |
629 #define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds) | |
630 #define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size) | |
631 | |
632 #define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32 | |
633 | |
634 struct _MDCPU { | |
635 struct _MDCPU_Unix md_unix; | |
636 }; | |
637 | |
638 #define _MD_INIT_LOCKS() | |
639 #define _MD_NEW_LOCK(lock) PR_SUCCESS | |
640 #define _MD_FREE_LOCK(lock) | |
641 #define _MD_LOCK(lock) | |
642 #define _MD_UNLOCK(lock) | |
643 #define _MD_INIT_IO() | |
644 #define _MD_IOQ_LOCK() | |
645 #define _MD_IOQ_UNLOCK() | |
646 | |
647 extern PRStatus _MD_InitializeThread(PRThread *thread); | |
648 | |
649 #define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu) | |
650 #define _MD_INIT_THREAD _MD_InitializeThread | |
651 #define _MD_EXIT_THREAD(thread) | |
652 #define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread | |
653 #define _MD_RESUME_THREAD(thread) _MD_resume_thread | |
654 #define _MD_CLEAN_THREAD(_thread) | |
655 | |
656 extern PRStatus _MD_CREATE_THREAD( | |
657 PRThread *thread, | |
658 void (*start) (void *), | |
659 PRThreadPriority priority, | |
660 PRThreadScope scope, | |
661 PRThreadState state, | |
662 PRUint32 stackSize); | |
663 extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri); | |
664 extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout); | |
665 extern PRStatus _MD_WAKEUP_WAITER(PRThread *); | |
666 extern void _MD_YIELD(void); | |
667 | |
668 #endif /* ! _PR_PTHREADS */ | |
669 | |
670 extern void _MD_EarlyInit(void); | |
671 | |
672 #define _MD_EARLY_INIT _MD_EarlyInit | |
673 #define _MD_FINAL_INIT _PR_UnixInit | |
674 #define _PR_HAVE_CLOCK_MONOTONIC | |
675 | |
676 /* | |
677 * We wrapped the select() call. _MD_SELECT refers to the built-in, | |
678 * unwrapped version. | |
679 */ | |
680 #define _MD_SELECT __select | |
681 | |
682 #ifdef _PR_POLL_AVAILABLE | |
683 #include <sys/poll.h> | |
684 extern int __syscall_poll(struct pollfd *ufds, unsigned long int nfds, | |
685 int timeout); | |
686 #define _MD_POLL __syscall_poll | |
687 #endif | |
688 | |
689 /* For writev() */ | |
690 #include <sys/uio.h> | |
691 | |
692 extern void _MD_linux_map_sendfile_error(int err); | |
693 | |
694 #endif /* nspr_linux_defs_h___ */ | |
OLD | NEW |