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