Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: obsolete/breakpad/common/linux/linux_syscall_support.h

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /* Copyright (c) 2005-2008, Google Inc.
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * ---
31 * Author: Markus Gutschke
32 */
33
34 /* This file includes Linux-specific support functions common to the
35 * coredumper and the thread lister; primarily, this is a collection
36 * of direct system calls, and a couple of symbols missing from
37 * standard header files.
38 * There are a few options that the including file can set to control
39 * the behavior of this file:
40 *
41 * SYS_CPLUSPLUS:
42 * The entire header file will normally be wrapped in 'extern "C" { }",
43 * making it suitable for compilation as both C and C++ source. If you
44 * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit
45 * the wrapping. N.B. doing so will suppress inclusion of all prerequisite
46 * system header files, too. It is the caller's responsibility to provide
47 * the necessary definitions.
48 *
49 * SYS_ERRNO:
50 * All system calls will update "errno" unless overriden by setting the
51 * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be
52 * an l-value.
53 *
54 * SYS_INLINE:
55 * New symbols will be defined "static inline", unless overridden by
56 * the SYS_INLINE macro.
57 *
58 * SYS_LINUX_SYSCALL_SUPPORT_H
59 * This macro is used to avoid multiple inclusions of this header file.
60 * If you need to include this file more than once, make sure to
61 * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion.
62 *
63 * SYS_PREFIX:
64 * New system calls will have a prefix of "sys_" unless overridden by
65 * the SYS_PREFIX macro. Valid values for this macro are [0..9] which
66 * results in prefixes "sys[0..9]_". It is also possible to set this
67 * macro to -1, which avoids all prefixes.
68 *
69 * This file defines a few internal symbols that all start with "LSS_".
70 * Do not access these symbols from outside this file. They are not part
71 * of the supported API.
72 */
73 #ifndef SYS_LINUX_SYSCALL_SUPPORT_H
74 #define SYS_LINUX_SYSCALL_SUPPORT_H
75
76 /* We currently only support x86-32, x86-64, ARM, MIPS, and PPC on Linux.
77 * Porting to other related platforms should not be difficult.
78 */
79 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
80 defined(__mips__) || defined(__PPC__) || defined(__ARM_EABI__)) \
81 && defined(__linux)
82
83 #ifndef SYS_CPLUSPLUS
84 #ifdef __cplusplus
85 /* Some system header files in older versions of gcc neglect to properly
86 * handle being included from C++. As it appears to be harmless to have
87 * multiple nested 'extern "C"' blocks, just add another one here.
88 */
89 extern "C" {
90 #endif
91
92 #include <errno.h>
93 #include <signal.h>
94 #include <stdarg.h>
95 #include <string.h>
96 #include <sys/ptrace.h>
97 #include <sys/resource.h>
98 #include <sys/time.h>
99 #include <sys/types.h>
100 #include <syscall.h>
101 #include <unistd.h>
102 #include <linux/unistd.h>
103 #include <endian.h>
104
105 #ifdef __mips__
106 /* Include definitions of the ABI currently in use. */
107 #include <sgidefs.h>
108 #endif
109 #endif
110
111 /* As glibc often provides subtly incompatible data structures (and implicit
112 * wrapper functions that convert them), we provide our own kernel data
113 * structures for use by the system calls.
114 * These structures have been developed by using Linux 2.6.23 headers for
115 * reference. Note though, we do not care about exact API compatibility
116 * with the kernel, and in fact the kernel often does not have a single
117 * API that works across architectures. Instead, we try to mimic the glibc
118 * API where reasonable, and only guarantee ABI compatibility with the
119 * kernel headers.
120 * Most notably, here are a few changes that were made to the structures
121 * defined by kernel headers:
122 *
123 * - we only define structures, but not symbolic names for kernel data
124 * types. For the latter, we directly use the native C datatype
125 * (i.e. "unsigned" instead of "mode_t").
126 * - in a few cases, it is possible to define identical structures for
127 * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by
128 * standardizing on the 64bit version of the data types. In particular,
129 * this means that we use "unsigned" where the 32bit headers say
130 * "unsigned long".
131 * - overall, we try to minimize the number of cases where we need to
132 * conditionally define different structures.
133 * - the "struct kernel_sigaction" class of structures have been
134 * modified to more closely mimic glibc's API by introducing an
135 * anonymous union for the function pointer.
136 * - a small number of field names had to have an underscore appended to
137 * them, because glibc defines a global macro by the same name.
138 */
139
140 /* include/linux/dirent.h */
141 struct kernel_dirent64 {
142 unsigned long long d_ino;
143 long long d_off;
144 unsigned short d_reclen;
145 unsigned char d_type;
146 char d_name[256];
147 };
148
149 /* include/linux/dirent.h */
150 struct kernel_dirent {
151 long d_ino;
152 long d_off;
153 unsigned short d_reclen;
154 char d_name[256];
155 };
156
157 /* include/linux/uio.h */
158 struct kernel_iovec {
159 void *iov_base;
160 unsigned long iov_len;
161 };
162
163 /* include/linux/socket.h */
164 struct kernel_msghdr {
165 void *msg_name;
166 int msg_namelen;
167 struct kernel_iovec*msg_iov;
168 unsigned long msg_iovlen;
169 void *msg_control;
170 unsigned long msg_controllen;
171 unsigned msg_flags;
172 };
173
174 /* include/asm-generic/poll.h */
175 struct kernel_pollfd {
176 int fd;
177 short events;
178 short revents;
179 };
180
181 /* include/linux/resource.h */
182 struct kernel_rlimit {
183 unsigned long rlim_cur;
184 unsigned long rlim_max;
185 };
186
187 /* include/linux/time.h */
188 struct kernel_timespec {
189 long tv_sec;
190 long tv_nsec;
191 };
192
193 /* include/linux/time.h */
194 struct kernel_timeval {
195 long tv_sec;
196 long tv_usec;
197 };
198
199 /* include/linux/resource.h */
200 struct kernel_rusage {
201 struct kernel_timeval ru_utime;
202 struct kernel_timeval ru_stime;
203 long ru_maxrss;
204 long ru_ixrss;
205 long ru_idrss;
206 long ru_isrss;
207 long ru_minflt;
208 long ru_majflt;
209 long ru_nswap;
210 long ru_inblock;
211 long ru_oublock;
212 long ru_msgsnd;
213 long ru_msgrcv;
214 long ru_nsignals;
215 long ru_nvcsw;
216 long ru_nivcsw;
217 };
218
219 struct siginfo;
220 #if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \
221 || defined(__PPC__)
222
223 /* include/asm-{arm,i386,mips,ppc}/signal.h */
224 struct kernel_old_sigaction {
225 union {
226 void (*sa_handler_)(int);
227 void (*sa_sigaction_)(int, struct siginfo *, void *);
228 };
229 unsigned long sa_mask;
230 unsigned long sa_flags;
231 void (*sa_restorer)(void);
232 } __attribute__((packed,aligned(4)));
233 #elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
234 #define kernel_old_sigaction kernel_sigaction
235 #endif
236
237 /* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
238 * exactly match the size of the signal set, even though the API was
239 * intended to be extensible. We define our own KERNEL_NSIG to deal with
240 * this.
241 * Please note that glibc provides signals [1.._NSIG-1], whereas the
242 * kernel (and this header) provides the range [1..KERNEL_NSIG]. The
243 * actual number of signals is obviously the same, but the constants
244 * differ by one.
245 */
246 #ifdef __mips__
247 #define KERNEL_NSIG 128
248 #else
249 #define KERNEL_NSIG 64
250 #endif
251
252 /* include/asm-{arm,i386,mips,x86_64}/signal.h */
253 struct kernel_sigset_t {
254 unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
255 (8*sizeof(unsigned long))];
256 };
257
258 /* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */
259 struct kernel_sigaction {
260 #ifdef __mips__
261 unsigned long sa_flags;
262 union {
263 void (*sa_handler_)(int);
264 void (*sa_sigaction_)(int, struct siginfo *, void *);
265 };
266 struct kernel_sigset_t sa_mask;
267 #else
268 union {
269 void (*sa_handler_)(int);
270 void (*sa_sigaction_)(int, struct siginfo *, void *);
271 };
272 unsigned long sa_flags;
273 void (*sa_restorer)(void);
274 struct kernel_sigset_t sa_mask;
275 #endif
276 };
277
278 /* include/linux/socket.h */
279 struct kernel_sockaddr {
280 unsigned short sa_family;
281 char sa_data[14];
282 };
283
284 /* include/asm-{arm,i386,mips,ppc}/stat.h */
285 #ifdef __mips__
286 #if _MIPS_SIM == _MIPS_SIM_ABI64
287 struct kernel_stat {
288 #else
289 struct kernel_stat64 {
290 #endif
291 unsigned st_dev;
292 unsigned __pad0[3];
293 unsigned long long st_ino;
294 unsigned st_mode;
295 unsigned st_nlink;
296 unsigned st_uid;
297 unsigned st_gid;
298 unsigned st_rdev;
299 unsigned __pad1[3];
300 long long st_size;
301 unsigned st_atime_;
302 unsigned st_atime_nsec_;
303 unsigned st_mtime_;
304 unsigned st_mtime_nsec_;
305 unsigned st_ctime_;
306 unsigned st_ctime_nsec_;
307 unsigned st_blksize;
308 unsigned __pad2;
309 unsigned long long st_blocks;
310 };
311 #elif defined __PPC__
312 struct kernel_stat64 {
313 unsigned long long st_dev;
314 unsigned long long st_ino;
315 unsigned st_mode;
316 unsigned st_nlink;
317 unsigned st_uid;
318 unsigned st_gid;
319 unsigned long long st_rdev;
320 unsigned short int __pad2;
321 long long st_size;
322 long st_blksize;
323 long long st_blocks;
324 long st_atime_;
325 unsigned long st_atime_nsec_;
326 long st_mtime_;
327 unsigned long st_mtime_nsec_;
328 long st_ctime_;
329 unsigned long st_ctime_nsec_;
330 unsigned long __unused4;
331 unsigned long __unused5;
332 };
333 #else
334 struct kernel_stat64 {
335 unsigned long long st_dev;
336 unsigned char __pad0[4];
337 unsigned __st_ino;
338 unsigned st_mode;
339 unsigned st_nlink;
340 unsigned st_uid;
341 unsigned st_gid;
342 unsigned long long st_rdev;
343 unsigned char __pad3[4];
344 long long st_size;
345 unsigned st_blksize;
346 unsigned long long st_blocks;
347 unsigned st_atime_;
348 unsigned st_atime_nsec_;
349 unsigned st_mtime_;
350 unsigned st_mtime_nsec_;
351 unsigned st_ctime_;
352 unsigned st_ctime_nsec_;
353 unsigned long long st_ino;
354 };
355 #endif
356
357 /* include/asm-{arm,i386,mips,x86_64,ppc}/stat.h */
358 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
359 struct kernel_stat {
360 /* The kernel headers suggest that st_dev and st_rdev should be 32bit
361 * quantities encoding 12bit major and 20bit minor numbers in an interleaved
362 * format. In reality, we do not see useful data in the top bits. So,
363 * we'll leave the padding in here, until we find a better solution.
364 */
365 unsigned short st_dev;
366 short pad1;
367 unsigned st_ino;
368 unsigned short st_mode;
369 unsigned short st_nlink;
370 unsigned short st_uid;
371 unsigned short st_gid;
372 unsigned short st_rdev;
373 short pad2;
374 unsigned st_size;
375 unsigned st_blksize;
376 unsigned st_blocks;
377 unsigned st_atime_;
378 unsigned st_atime_nsec_;
379 unsigned st_mtime_;
380 unsigned st_mtime_nsec_;
381 unsigned st_ctime_;
382 unsigned st_ctime_nsec_;
383 unsigned __unused4;
384 unsigned __unused5;
385 };
386 #elif defined(__x86_64__)
387 struct kernel_stat {
388 unsigned long st_dev;
389 unsigned long st_ino;
390 unsigned long st_nlink;
391 unsigned st_mode;
392 unsigned st_uid;
393 unsigned st_gid;
394 unsigned __pad0;
395 unsigned long st_rdev;
396 long st_size;
397 long st_blksize;
398 long st_blocks;
399 unsigned long st_atime_;
400 unsigned long st_atime_nsec_;
401 unsigned long st_mtime_;
402 unsigned long st_mtime_nsec_;
403 unsigned long st_ctime_;
404 unsigned long st_ctime_nsec_;
405 long __unused[3];
406 };
407 #elif defined(__PPC__)
408 struct kernel_stat {
409 unsigned st_dev;
410 unsigned long st_ino; // ino_t
411 unsigned long st_mode; // mode_t
412 unsigned short st_nlink; // nlink_t
413 unsigned st_uid; // uid_t
414 unsigned st_gid; // gid_t
415 unsigned st_rdev;
416 long st_size; // off_t
417 unsigned long st_blksize;
418 unsigned long st_blocks;
419 unsigned long st_atime_;
420 unsigned long st_atime_nsec_;
421 unsigned long st_mtime_;
422 unsigned long st_mtime_nsec_;
423 unsigned long st_ctime_;
424 unsigned long st_ctime_nsec_;
425 unsigned long __unused4;
426 unsigned long __unused5;
427 };
428 #elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)
429 struct kernel_stat {
430 unsigned st_dev;
431 int st_pad1[3];
432 unsigned st_ino;
433 unsigned st_mode;
434 unsigned st_nlink;
435 unsigned st_uid;
436 unsigned st_gid;
437 unsigned st_rdev;
438 int st_pad2[2];
439 long st_size;
440 int st_pad3;
441 long st_atime_;
442 long st_atime_nsec_;
443 long st_mtime_;
444 long st_mtime_nsec_;
445 long st_ctime_;
446 long st_ctime_nsec_;
447 int st_blksize;
448 int st_blocks;
449 int st_pad4[14];
450 };
451 #endif
452
453 /* include/asm-{arm,i386,mips,x86_64,ppc}/statfs.h */
454 #ifdef __mips__
455 #if _MIPS_SIM != _MIPS_SIM_ABI64
456 struct kernel_statfs64 {
457 unsigned long f_type;
458 unsigned long f_bsize;
459 unsigned long f_frsize;
460 unsigned long __pad;
461 unsigned long long f_blocks;
462 unsigned long long f_bfree;
463 unsigned long long f_files;
464 unsigned long long f_ffree;
465 unsigned long long f_bavail;
466 struct { int val[2]; } f_fsid;
467 unsigned long f_namelen;
468 unsigned long f_spare[6];
469 };
470 #endif
471 #elif !defined(__x86_64__)
472 struct kernel_statfs64 {
473 unsigned long f_type;
474 unsigned long f_bsize;
475 unsigned long long f_blocks;
476 unsigned long long f_bfree;
477 unsigned long long f_bavail;
478 unsigned long long f_files;
479 unsigned long long f_ffree;
480 struct { int val[2]; } f_fsid;
481 unsigned long f_namelen;
482 unsigned long f_frsize;
483 unsigned long f_spare[5];
484 };
485 #endif
486
487 /* include/asm-{arm,i386,mips,x86_64,ppc,generic}/statfs.h */
488 #ifdef __mips__
489 struct kernel_statfs {
490 long f_type;
491 long f_bsize;
492 long f_frsize;
493 long f_blocks;
494 long f_bfree;
495 long f_files;
496 long f_ffree;
497 long f_bavail;
498 struct { int val[2]; } f_fsid;
499 long f_namelen;
500 long f_spare[6];
501 };
502 #else
503 struct kernel_statfs {
504 /* x86_64 actually defines all these fields as signed, whereas all other */
505 /* platforms define them as unsigned. Leaving them at unsigned should not */
506 /* cause any problems. */
507 unsigned long f_type;
508 unsigned long f_bsize;
509 unsigned long f_blocks;
510 unsigned long f_bfree;
511 unsigned long f_bavail;
512 unsigned long f_files;
513 unsigned long f_ffree;
514 struct { int val[2]; } f_fsid;
515 unsigned long f_namelen;
516 unsigned long f_frsize;
517 unsigned long f_spare[5];
518 };
519 #endif
520
521
522 /* Definitions missing from the standard header files */
523 #ifndef O_DIRECTORY
524 #if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
525 #define O_DIRECTORY 0040000
526 #else
527 #define O_DIRECTORY 0200000
528 #endif
529 #endif
530 #ifndef NT_PRXFPREG
531 #define NT_PRXFPREG 0x46e62b7f
532 #endif
533 #ifndef PTRACE_GETFPXREGS
534 #define PTRACE_GETFPXREGS ((enum __ptrace_request)18)
535 #endif
536 #ifndef PR_GET_DUMPABLE
537 #define PR_GET_DUMPABLE 3
538 #endif
539 #ifndef PR_SET_DUMPABLE
540 #define PR_SET_DUMPABLE 4
541 #endif
542 #ifndef AT_FDCWD
543 #define AT_FDCWD (-100)
544 #endif
545 #ifndef AT_SYMLINK_NOFOLLOW
546 #define AT_SYMLINK_NOFOLLOW 0x100
547 #endif
548 #ifndef AT_REMOVEDIR
549 #define AT_REMOVEDIR 0x200
550 #endif
551 #ifndef MREMAP_FIXED
552 #define MREMAP_FIXED 2
553 #endif
554 #ifndef SA_RESTORER
555 #define SA_RESTORER 0x04000000
556 #endif
557
558 #if defined(__i386__)
559 #ifndef __NR_setresuid
560 #define __NR_setresuid 164
561 #define __NR_setresgid 170
562 #endif
563 #ifndef __NR_rt_sigaction
564 #define __NR_rt_sigaction 174
565 #define __NR_rt_sigprocmask 175
566 #define __NR_rt_sigpending 176
567 #define __NR_rt_sigsuspend 179
568 #endif
569 #ifndef __NR_pread64
570 #define __NR_pread64 180
571 #endif
572 #ifndef __NR_pwrite64
573 #define __NR_pwrite64 181
574 #endif
575 #ifndef __NR_ugetrlimit
576 #define __NR_ugetrlimit 191
577 #endif
578 #ifndef __NR_stat64
579 #define __NR_stat64 195
580 #endif
581 #ifndef __NR_fstat64
582 #define __NR_fstat64 197
583 #endif
584 #ifndef __NR_setresuid32
585 #define __NR_setresuid32 208
586 #define __NR_setresgid32 210
587 #endif
588 #ifndef __NR_setfsuid32
589 #define __NR_setfsuid32 215
590 #define __NR_setfsgid32 216
591 #endif
592 #ifndef __NR_getdents64
593 #define __NR_getdents64 220
594 #endif
595 #ifndef __NR_gettid
596 #define __NR_gettid 224
597 #endif
598 #ifndef __NR_readahead
599 #define __NR_readahead 225
600 #endif
601 #ifndef __NR_setxattr
602 #define __NR_setxattr 226
603 #endif
604 #ifndef __NR_lsetxattr
605 #define __NR_lsetxattr 227
606 #endif
607 #ifndef __NR_getxattr
608 #define __NR_getxattr 229
609 #endif
610 #ifndef __NR_lgetxattr
611 #define __NR_lgetxattr 230
612 #endif
613 #ifndef __NR_futex
614 #define __NR_futex 240
615 #endif
616 #ifndef __NR_sched_setaffinity
617 #define __NR_sched_setaffinity 241
618 #define __NR_sched_getaffinity 242
619 #endif
620 #ifndef __NR_set_tid_address
621 #define __NR_set_tid_address 258
622 #endif
623 #ifndef __NR_statfs64
624 #define __NR_statfs64 268
625 #endif
626 #ifndef __NR_fstatfs64
627 #define __NR_fstatfs64 269
628 #endif
629 #ifndef __NR_fadvise64_64
630 #define __NR_fadvise64_64 272
631 #endif
632 #ifndef __NR_openat
633 #define __NR_openat 295
634 #endif
635 #ifndef __NR_fstatat64
636 #define __NR_fstatat64 300
637 #endif
638 #ifndef __NR_unlinkat
639 #define __NR_unlinkat 301
640 #endif
641 #ifndef __NR_move_pages
642 #define __NR_move_pages 317
643 #endif
644 /* End of i386 definitions */
645 #elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
646 #ifndef __NR_setresuid
647 #define __NR_setresuid (__NR_SYSCALL_BASE + 164)
648 #define __NR_setresgid (__NR_SYSCALL_BASE + 170)
649 #endif
650 #ifndef __NR_rt_sigaction
651 #define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
652 #define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
653 #define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
654 #define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
655 #endif
656 #ifndef __NR_pread64
657 #define __NR_pread64 (__NR_SYSCALL_BASE + 180)
658 #endif
659 #ifndef __NR_pwrite64
660 #define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
661 #endif
662 #ifndef __NR_ugetrlimit
663 #define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
664 #endif
665 #ifndef __NR_stat64
666 #define __NR_stat64 (__NR_SYSCALL_BASE + 195)
667 #endif
668 #ifndef __NR_fstat64
669 #define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
670 #endif
671 #ifndef __NR_setresuid32
672 #define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
673 #define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
674 #endif
675 #ifndef __NR_setfsuid32
676 #define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
677 #define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
678 #endif
679 #ifndef __NR_getdents64
680 #define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
681 #endif
682 #ifndef __NR_gettid
683 #define __NR_gettid (__NR_SYSCALL_BASE + 224)
684 #endif
685 #ifndef __NR_readahead
686 #define __NR_readahead (__NR_SYSCALL_BASE + 225)
687 #endif
688 #ifndef __NR_setxattr
689 #define __NR_setxattr (__NR_SYSCALL_BASE + 226)
690 #endif
691 #ifndef __NR_lsetxattr
692 #define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
693 #endif
694 #ifndef __NR_getxattr
695 #define __NR_getxattr (__NR_SYSCALL_BASE + 229)
696 #endif
697 #ifndef __NR_lgetxattr
698 #define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
699 #endif
700 #ifndef __NR_futex
701 #define __NR_futex (__NR_SYSCALL_BASE + 240)
702 #endif
703 #ifndef __NR_sched_setaffinity
704 #define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
705 #define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
706 #endif
707 #ifndef __NR_set_tid_address
708 #define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
709 #endif
710 #ifndef __NR_statfs64
711 #define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
712 #endif
713 #ifndef __NR_fstatfs64
714 #define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
715 #endif
716 #ifndef __NR_move_pages
717 #define __NR_move_pages (__NR_SYSCALL_BASE + 344)
718 #endif
719 /* End of ARM 3/EABI definitions */
720 #elif defined(__x86_64__)
721 #ifndef __NR_setresuid
722 #define __NR_setresuid 117
723 #define __NR_setresgid 119
724 #endif
725 #ifndef __NR_gettid
726 #define __NR_gettid 186
727 #endif
728 #ifndef __NR_readahead
729 #define __NR_readahead 187
730 #endif
731 #ifndef __NR_setxattr
732 #define __NR_setxattr 188
733 #endif
734 #ifndef __NR_lsetxattr
735 #define __NR_lsetxattr 189
736 #endif
737 #ifndef __NR_getxattr
738 #define __NR_getxattr 191
739 #endif
740 #ifndef __NR_lgetxattr
741 #define __NR_lgetxattr 192
742 #endif
743 #ifndef __NR_futex
744 #define __NR_futex 202
745 #endif
746 #ifndef __NR_sched_setaffinity
747 #define __NR_sched_setaffinity 203
748 #define __NR_sched_getaffinity 204
749 #endif
750 #ifndef __NR_getdents64
751 #define __NR_getdents64 217
752 #endif
753 #ifndef __NR_set_tid_address
754 #define __NR_set_tid_address 218
755 #endif
756 #ifndef __NR_fadvise64
757 #define __NR_fadvise64 221
758 #endif
759 #ifndef __NR_openat
760 #define __NR_openat 257
761 #endif
762 #ifndef __NR_newfstatat
763 #define __NR_newfstatat 262
764 #endif
765 #ifndef __NR_unlinkat
766 #define __NR_unlinkat 263
767 #endif
768 #ifndef __NR_move_pages
769 #define __NR_move_pages 279
770 #endif
771 /* End of x86-64 definitions */
772 #elif defined(__mips__)
773 #if _MIPS_SIM == _MIPS_SIM_ABI32
774 #ifndef __NR_setresuid
775 #define __NR_setresuid (__NR_Linux + 185)
776 #define __NR_setresgid (__NR_Linux + 190)
777 #endif
778 #ifndef __NR_rt_sigaction
779 #define __NR_rt_sigaction (__NR_Linux + 194)
780 #define __NR_rt_sigprocmask (__NR_Linux + 195)
781 #define __NR_rt_sigpending (__NR_Linux + 196)
782 #define __NR_rt_sigsuspend (__NR_Linux + 199)
783 #endif
784 #ifndef __NR_pread64
785 #define __NR_pread64 (__NR_Linux + 200)
786 #endif
787 #ifndef __NR_pwrite64
788 #define __NR_pwrite64 (__NR_Linux + 201)
789 #endif
790 #ifndef __NR_stat64
791 #define __NR_stat64 (__NR_Linux + 213)
792 #endif
793 #ifndef __NR_fstat64
794 #define __NR_fstat64 (__NR_Linux + 215)
795 #endif
796 #ifndef __NR_getdents64
797 #define __NR_getdents64 (__NR_Linux + 219)
798 #endif
799 #ifndef __NR_gettid
800 #define __NR_gettid (__NR_Linux + 222)
801 #endif
802 #ifndef __NR_readahead
803 #define __NR_readahead (__NR_Linux + 223)
804 #endif
805 #ifndef __NR_setxattr
806 #define __NR_setxattr (__NR_Linux + 224)
807 #endif
808 #ifndef __NR_lsetxattr
809 #define __NR_lsetxattr (__NR_Linux + 225)
810 #endif
811 #ifndef __NR_getxattr
812 #define __NR_getxattr (__NR_Linux + 227)
813 #endif
814 #ifndef __NR_lgetxattr
815 #define __NR_lgetxattr (__NR_Linux + 228)
816 #endif
817 #ifndef __NR_futex
818 #define __NR_futex (__NR_Linux + 238)
819 #endif
820 #ifndef __NR_sched_setaffinity
821 #define __NR_sched_setaffinity (__NR_Linux + 239)
822 #define __NR_sched_getaffinity (__NR_Linux + 240)
823 #endif
824 #ifndef __NR_set_tid_address
825 #define __NR_set_tid_address (__NR_Linux + 252)
826 #endif
827 #ifndef __NR_statfs64
828 #define __NR_statfs64 (__NR_Linux + 255)
829 #endif
830 #ifndef __NR_fstatfs64
831 #define __NR_fstatfs64 (__NR_Linux + 256)
832 #endif
833 #ifndef __NR_openat
834 #define __NR_openat (__NR_Linux + 288)
835 #endif
836 #ifndef __NR_fstatat
837 #define __NR_fstatat (__NR_Linux + 293)
838 #endif
839 #ifndef __NR_unlinkat
840 #define __NR_unlinkat (__NR_Linux + 294)
841 #endif
842 #ifndef __NR_move_pages
843 #define __NR_move_pages (__NR_Linux + 308)
844 #endif
845 /* End of MIPS (old 32bit API) definitions */
846 #elif _MIPS_SIM == _MIPS_SIM_ABI64
847 #ifndef __NR_setresuid
848 #define __NR_setresuid (__NR_Linux + 115)
849 #define __NR_setresgid (__NR_Linux + 117)
850 #endif
851 #ifndef __NR_gettid
852 #define __NR_gettid (__NR_Linux + 178)
853 #endif
854 #ifndef __NR_readahead
855 #define __NR_readahead (__NR_Linux + 179)
856 #endif
857 #ifndef __NR_setxattr
858 #define __NR_setxattr (__NR_Linux + 180)
859 #endif
860 #ifndef __NR_lsetxattr
861 #define __NR_lsetxattr (__NR_Linux + 181)
862 #endif
863 #ifndef __NR_getxattr
864 #define __NR_getxattr (__NR_Linux + 183)
865 #endif
866 #ifndef __NR_lgetxattr
867 #define __NR_lgetxattr (__NR_Linux + 184)
868 #endif
869 #ifndef __NR_futex
870 #define __NR_futex (__NR_Linux + 194)
871 #endif
872 #ifndef __NR_sched_setaffinity
873 #define __NR_sched_setaffinity (__NR_Linux + 195)
874 #define __NR_sched_getaffinity (__NR_Linux + 196)
875 #endif
876 #ifndef __NR_set_tid_address
877 #define __NR_set_tid_address (__NR_Linux + 212)
878 #endif
879 #ifndef __NR_openat
880 #define __NR_openat (__NR_Linux + 247)
881 #endif
882 #ifndef __NR_fstatat
883 #define __NR_fstatat (__NR_Linux + 252)
884 #endif
885 #ifndef __NR_unlinkat
886 #define __NR_unlinkat (__NR_Linux + 253)
887 #endif
888 #ifndef __NR_move_pages
889 #define __NR_move_pages (__NR_Linux + 267)
890 #endif
891 /* End of MIPS (64bit API) definitions */
892 #else
893 #ifndef __NR_setresuid
894 #define __NR_setresuid (__NR_Linux + 115)
895 #define __NR_setresgid (__NR_Linux + 117)
896 #endif
897 #ifndef __NR_gettid
898 #define __NR_gettid (__NR_Linux + 178)
899 #endif
900 #ifndef __NR_readahead
901 #define __NR_readahead (__NR_Linux + 179)
902 #endif
903 #ifndef __NR_setxattr
904 #define __NR_setxattr (__NR_Linux + 180)
905 #endif
906 #ifndef __NR_lsetxattr
907 #define __NR_lsetxattr (__NR_Linux + 181)
908 #endif
909 #ifndef __NR_getxattr
910 #define __NR_getxattr (__NR_Linux + 183)
911 #endif
912 #ifndef __NR_lgetxattr
913 #define __NR_lgetxattr (__NR_Linux + 184)
914 #endif
915 #ifndef __NR_futex
916 #define __NR_futex (__NR_Linux + 194)
917 #endif
918 #ifndef __NR_sched_setaffinity
919 #define __NR_sched_setaffinity (__NR_Linux + 195)
920 #define __NR_sched_getaffinity (__NR_Linux + 196)
921 #endif
922 #ifndef __NR_set_tid_address
923 #define __NR_set_tid_address (__NR_Linux + 213)
924 #endif
925 #ifndef __NR_statfs64
926 #define __NR_statfs64 (__NR_Linux + 217)
927 #endif
928 #ifndef __NR_fstatfs64
929 #define __NR_fstatfs64 (__NR_Linux + 218)
930 #endif
931 #ifndef __NR_openat
932 #define __NR_openat (__NR_Linux + 251)
933 #endif
934 #ifndef __NR_fstatat
935 #define __NR_fstatat (__NR_Linux + 256)
936 #endif
937 #ifndef __NR_unlinkat
938 #define __NR_unlinkat (__NR_Linux + 257)
939 #endif
940 #ifndef __NR_move_pages
941 #define __NR_move_pages (__NR_Linux + 271)
942 #endif
943 /* End of MIPS (new 32bit API) definitions */
944 #endif
945 /* End of MIPS definitions */
946 #elif defined(__PPC__)
947 #ifndef __NR_setfsuid
948 #define __NR_setfsuid 138
949 #define __NR_setfsgid 139
950 #endif
951 #ifndef __NR_setresuid
952 #define __NR_setresuid 164
953 #define __NR_setresgid 169
954 #endif
955 #ifndef __NR_rt_sigaction
956 #define __NR_rt_sigaction 173
957 #define __NR_rt_sigprocmask 174
958 #define __NR_rt_sigpending 175
959 #define __NR_rt_sigsuspend 178
960 #endif
961 #ifndef __NR_pread64
962 #define __NR_pread64 179
963 #endif
964 #ifndef __NR_pwrite64
965 #define __NR_pwrite64 180
966 #endif
967 #ifndef __NR_ugetrlimit
968 #define __NR_ugetrlimit 190
969 #endif
970 #ifndef __NR_readahead
971 #define __NR_readahead 191
972 #endif
973 #ifndef __NR_stat64
974 #define __NR_stat64 195
975 #endif
976 #ifndef __NR_fstat64
977 #define __NR_fstat64 197
978 #endif
979 #ifndef __NR_getdents64
980 #define __NR_getdents64 202
981 #endif
982 #ifndef __NR_gettid
983 #define __NR_gettid 207
984 #endif
985 #ifndef __NR_setxattr
986 #define __NR_setxattr 209
987 #endif
988 #ifndef __NR_lsetxattr
989 #define __NR_lsetxattr 210
990 #endif
991 #ifndef __NR_getxattr
992 #define __NR_getxattr 212
993 #endif
994 #ifndef __NR_lgetxattr
995 #define __NR_lgetxattr 213
996 #endif
997 #ifndef __NR_futex
998 #define __NR_futex 221
999 #endif
1000 #ifndef __NR_sched_setaffinity
1001 #define __NR_sched_setaffinity 222
1002 #define __NR_sched_getaffinity 223
1003 #endif
1004 #ifndef __NR_set_tid_address
1005 #define __NR_set_tid_address 232
1006 #endif
1007 #ifndef __NR_statfs64
1008 #define __NR_statfs64 252
1009 #endif
1010 #ifndef __NR_fstatfs64
1011 #define __NR_fstatfs64 253
1012 #endif
1013 #ifndef __NR_fadvise64_64
1014 #define __NR_fadvise64_64 254
1015 #endif
1016 #ifndef __NR_openat
1017 #define __NR_openat 286
1018 #endif
1019 #ifndef __NR_fstatat64
1020 #define __NR_fstatat64 291
1021 #endif
1022 #ifndef __NR_unlinkat
1023 #define __NR_unlinkat 292
1024 #endif
1025 #ifndef __NR_move_pages
1026 #define __NR_move_pages 301
1027 #endif
1028 /* End of powerpc defininitions */
1029 #endif
1030
1031
1032 /* After forking, we must make sure to only call system calls. */
1033 #if __BOUNDED_POINTERS__
1034 #error "Need to port invocations of syscalls for bounded ptrs"
1035 #else
1036 /* The core dumper and the thread lister get executed after threads
1037 * have been suspended. As a consequence, we cannot call any functions
1038 * that acquire locks. Unfortunately, libc wraps most system calls
1039 * (e.g. in order to implement pthread_atfork, and to make calls
1040 * cancellable), which means we cannot call these functions. Instead,
1041 * we have to call syscall() directly.
1042 */
1043 #undef LSS_ERRNO
1044 #ifdef SYS_ERRNO
1045 /* Allow the including file to override the location of errno. This can
1046 * be useful when using clone() with the CLONE_VM option.
1047 */
1048 #define LSS_ERRNO SYS_ERRNO
1049 #else
1050 #define LSS_ERRNO errno
1051 #endif
1052
1053 #undef LSS_INLINE
1054 #ifdef SYS_INLINE
1055 #define LSS_INLINE SYS_INLINE
1056 #else
1057 #define LSS_INLINE static inline
1058 #endif
1059
1060 /* Allow the including file to override the prefix used for all new
1061 * system calls. By default, it will be set to "sys_".
1062 */
1063 #undef LSS_NAME
1064 #ifndef SYS_PREFIX
1065 #define LSS_NAME(name) sys_##name
1066 #elif SYS_PREFIX < 0
1067 #define LSS_NAME(name) name
1068 #elif SYS_PREFIX == 0
1069 #define LSS_NAME(name) sys0_##name
1070 #elif SYS_PREFIX == 1
1071 #define LSS_NAME(name) sys1_##name
1072 #elif SYS_PREFIX == 2
1073 #define LSS_NAME(name) sys2_##name
1074 #elif SYS_PREFIX == 3
1075 #define LSS_NAME(name) sys3_##name
1076 #elif SYS_PREFIX == 4
1077 #define LSS_NAME(name) sys4_##name
1078 #elif SYS_PREFIX == 5
1079 #define LSS_NAME(name) sys5_##name
1080 #elif SYS_PREFIX == 6
1081 #define LSS_NAME(name) sys6_##name
1082 #elif SYS_PREFIX == 7
1083 #define LSS_NAME(name) sys7_##name
1084 #elif SYS_PREFIX == 8
1085 #define LSS_NAME(name) sys8_##name
1086 #elif SYS_PREFIX == 9
1087 #define LSS_NAME(name) sys9_##name
1088 #endif
1089
1090 #undef LSS_RETURN
1091 #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \
1092 || defined(__ARM_EABI__))
1093 /* Failing system calls return a negative result in the range of
1094 * -1..-4095. These are "errno" values with the sign inverted.
1095 */
1096 #define LSS_RETURN(type, res) \
1097 do { \
1098 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
1099 LSS_ERRNO = -(res); \
1100 res = -1; \
1101 } \
1102 return (type) (res); \
1103 } while (0)
1104 #elif defined(__mips__)
1105 /* On MIPS, failing system calls return -1, and set errno in a
1106 * separate CPU register.
1107 */
1108 #define LSS_RETURN(type, res, err) \
1109 do { \
1110 if (err) { \
1111 LSS_ERRNO = (res); \
1112 res = -1; \
1113 } \
1114 return (type) (res); \
1115 } while (0)
1116 #elif defined(__PPC__)
1117 /* On PPC, failing system calls return -1, and set errno in a
1118 * separate CPU register. See linux/unistd.h.
1119 */
1120 #define LSS_RETURN(type, res, err) \
1121 do { \
1122 if (err & 0x10000000 ) { \
1123 LSS_ERRNO = (res); \
1124 res = -1; \
1125 } \
1126 return (type) (res); \
1127 } while (0)
1128 #endif
1129 #if defined(__i386__)
1130 /* In PIC mode (e.g. when building shared libraries), gcc for i386
1131 * reserves ebx. Unfortunately, most distribution ship with implementations
1132 * of _syscallX() which clobber ebx.
1133 * Also, most definitions of _syscallX() neglect to mark "memory" as being
1134 * clobbered. This causes problems with compilers, that do a better job
1135 * at optimizing across __asm__ calls.
1136 * So, we just have to redefine all of the _syscallX() macros.
1137 */
1138 #undef LSS_BODY
1139 #define LSS_BODY(type,args...) \
1140 long __res; \
1141 __asm__ __volatile__("push %%ebx\n" \
1142 "movl %2,%%ebx\n" \
1143 "int $0x80\n" \
1144 "pop %%ebx" \
1145 args \
1146 : "memory"); \
1147 LSS_RETURN(type,__res)
1148 #undef _syscall0
1149 #define _syscall0(type,name) \
1150 type LSS_NAME(name)(void) { \
1151 long __res; \
1152 __asm__ volatile("int $0x80" \
1153 : "=a" (__res) \
1154 : "0" (__NR_##name) \
1155 : "memory"); \
1156 LSS_RETURN(type,__res); \
1157 }
1158 #undef _syscall1
1159 #define _syscall1(type,name,type1,arg1) \
1160 type LSS_NAME(name)(type1 arg1) { \
1161 LSS_BODY(type, \
1162 : "=a" (__res) \
1163 : "0" (__NR_##name), "ri" ((long)(arg1))); \
1164 }
1165 #undef _syscall2
1166 #define _syscall2(type,name,type1,arg1,type2,arg2) \
1167 type LSS_NAME(name)(type1 arg1,type2 arg2) { \
1168 LSS_BODY(type, \
1169 : "=a" (__res) \
1170 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
1171 }
1172 #undef _syscall3
1173 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
1174 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
1175 LSS_BODY(type, \
1176 : "=a" (__res) \
1177 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
1178 "d" ((long)(arg3))); \
1179 }
1180 #undef _syscall4
1181 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
1182 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
1183 LSS_BODY(type, \
1184 : "=a" (__res) \
1185 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
1186 "d" ((long)(arg3)),"S" ((long)(arg4))); \
1187 }
1188 #undef _syscall5
1189 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1190 type5,arg5) \
1191 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1192 type5 arg5) { \
1193 long __res; \
1194 __asm__ __volatile__("push %%ebx\n" \
1195 "movl %2,%%ebx\n" \
1196 "movl %1,%%eax\n" \
1197 "int $0x80\n" \
1198 "pop %%ebx" \
1199 : "=a" (__res) \
1200 : "i" (__NR_##name), "ri" ((long)(arg1)), \
1201 "c" ((long)(arg2)), "d" ((long)(arg3)), \
1202 "S" ((long)(arg4)), "D" ((long)(arg5)) \
1203 : "memory"); \
1204 LSS_RETURN(type,__res); \
1205 }
1206 #undef _syscall6
1207 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1208 type5,arg5,type6,arg6) \
1209 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1210 type5 arg5, type6 arg6) { \
1211 long __res; \
1212 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
1213 __asm__ __volatile__("push %%ebp\n" \
1214 "push %%ebx\n" \
1215 "movl 4(%2),%%ebp\n" \
1216 "movl 0(%2), %%ebx\n" \
1217 "movl %1,%%eax\n" \
1218 "int $0x80\n" \
1219 "pop %%ebx\n" \
1220 "pop %%ebp" \
1221 : "=a" (__res) \
1222 : "i" (__NR_##name), "0" ((long)(&__s)), \
1223 "c" ((long)(arg2)), "d" ((long)(arg3)), \
1224 "S" ((long)(arg4)), "D" ((long)(arg5)) \
1225 : "memory"); \
1226 LSS_RETURN(type,__res); \
1227 }
1228 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
1229 int flags, void *arg, int *parent_tidptr,
1230 void *newtls, int *child_tidptr) {
1231 long __res;
1232 __asm__ __volatile__(/* if (fn == NULL)
1233 * return -EINVAL;
1234 */
1235 "movl %3,%%ecx\n"
1236 "jecxz 1f\n"
1237
1238 /* if (child_stack == NULL)
1239 * return -EINVAL;
1240 */
1241 "movl %4,%%ecx\n"
1242 "jecxz 1f\n"
1243
1244 /* Set up alignment of the child stack:
1245 * child_stack = (child_stack & ~0xF) - 20;
1246 */
1247 "andl $-16,%%ecx\n"
1248 "subl $20,%%ecx\n"
1249
1250 /* Push "arg" and "fn" onto the stack that will be
1251 * used by the child.
1252 */
1253 "movl %6,%%eax\n"
1254 "movl %%eax,4(%%ecx)\n"
1255 "movl %3,%%eax\n"
1256 "movl %%eax,(%%ecx)\n"
1257
1258 /* %eax = syscall(%eax = __NR_clone,
1259 * %ebx = flags,
1260 * %ecx = child_stack,
1261 * %edx = parent_tidptr,
1262 * %esi = newtls,
1263 * %edi = child_tidptr)
1264 * Also, make sure that %ebx gets preserved as it is
1265 * used in PIC mode.
1266 */
1267 "movl %8,%%esi\n"
1268 "movl %7,%%edx\n"
1269 "movl %5,%%eax\n"
1270 "movl %9,%%edi\n"
1271 "pushl %%ebx\n"
1272 "movl %%eax,%%ebx\n"
1273 "movl %2,%%eax\n"
1274 "int $0x80\n"
1275
1276 /* In the parent: restore %ebx
1277 * In the child: move "fn" into %ebx
1278 */
1279 "popl %%ebx\n"
1280
1281 /* if (%eax != 0)
1282 * return %eax;
1283 */
1284 "test %%eax,%%eax\n"
1285 "jnz 1f\n"
1286
1287 /* In the child, now. Terminate frame pointer chain.
1288 */
1289 "movl $0,%%ebp\n"
1290
1291 /* Call "fn". "arg" is already on the stack.
1292 */
1293 "call *%%ebx\n"
1294
1295 /* Call _exit(%ebx). Unfortunately older versions
1296 * of gcc restrict the number of arguments that can
1297 * be passed to asm(). So, we need to hard-code the
1298 * system call number.
1299 */
1300 "movl %%eax,%%ebx\n"
1301 "movl $1,%%eax\n"
1302 "int $0x80\n"
1303
1304 /* Return to parent.
1305 */
1306 "1:\n"
1307 : "=a" (__res)
1308 : "0"(-EINVAL), "i"(__NR_clone),
1309 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
1310 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
1311 : "memory", "ecx", "edx", "esi", "edi");
1312 LSS_RETURN(int, __res);
1313 }
1314
1315 #define __NR__fadvise64_64 __NR_fadvise64_64
1316 LSS_INLINE _syscall6(int, _fadvise64_64, int, fd,
1317 unsigned, offset_lo, unsigned, offset_hi,
1318 unsigned, len_lo, unsigned, len_hi,
1319 int, advice)
1320
1321 LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,
1322 loff_t len, int advice) {
1323 return LSS_NAME(_fadvise64_64)(fd,
1324 (unsigned)offset, (unsigned)(offset >>32),
1325 (unsigned)len, (unsigned)(len >> 32),
1326 advice);
1327 }
1328
1329 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
1330 /* On i386, the kernel does not know how to return from a signal
1331 * handler. Instead, it relies on user space to provide a
1332 * restorer function that calls the {rt_,}sigreturn() system call.
1333 * Unfortunately, we cannot just reference the glibc version of this
1334 * function, as glibc goes out of its way to make it inaccessible.
1335 */
1336 void (*res)(void);
1337 __asm__ __volatile__("call 2f\n"
1338 "0:.align 16\n"
1339 "1:movl %1,%%eax\n"
1340 "int $0x80\n"
1341 "2:popl %0\n"
1342 "addl $(1b-0b),%0\n"
1343 : "=a" (res)
1344 : "i" (__NR_rt_sigreturn));
1345 return res;
1346 }
1347 LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
1348 /* On i386, the kernel does not know how to return from a signal
1349 * handler. Instead, it relies on user space to provide a
1350 * restorer function that calls the {rt_,}sigreturn() system call.
1351 * Unfortunately, we cannot just reference the glibc version of this
1352 * function, as glibc goes out of its way to make it inaccessible.
1353 */
1354 void (*res)(void);
1355 __asm__ __volatile__("call 2f\n"
1356 "0:.align 16\n"
1357 "1:pop %%eax\n"
1358 "movl %1,%%eax\n"
1359 "int $0x80\n"
1360 "2:popl %0\n"
1361 "addl $(1b-0b),%0\n"
1362 : "=a" (res)
1363 : "i" (__NR_sigreturn));
1364 return res;
1365 }
1366 #elif defined(__x86_64__)
1367 /* There are no known problems with any of the _syscallX() macros
1368 * currently shipping for x86_64, but we still need to be able to define
1369 * our own version so that we can override the location of the errno
1370 * location (e.g. when using the clone() system call with the CLONE_VM
1371 * option).
1372 */
1373 #undef LSS_BODY
1374 #define LSS_BODY(type,name, ...) \
1375 long __res; \
1376 __asm__ __volatile__("syscall" : "=a" (__res) : "0" (__NR_##name), \
1377 ##__VA_ARGS__ : "r11", "rcx", "memory"); \
1378 LSS_RETURN(type, __res)
1379 #undef _syscall0
1380 #define _syscall0(type,name) \
1381 type LSS_NAME(name)() { \
1382 LSS_BODY(type, name); \
1383 }
1384 #undef _syscall1
1385 #define _syscall1(type,name,type1,arg1) \
1386 type LSS_NAME(name)(type1 arg1) { \
1387 LSS_BODY(type, name, "D" ((long)(arg1))); \
1388 }
1389 #undef _syscall2
1390 #define _syscall2(type,name,type1,arg1,type2,arg2) \
1391 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
1392 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2))); \
1393 }
1394 #undef _syscall3
1395 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
1396 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
1397 LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2)), \
1398 "d" ((long)(arg3))); \
1399 }
1400 #undef _syscall4
1401 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
1402 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
1403 long __res; \
1404 __asm__ __volatile__("movq %5,%%r10; syscall" : \
1405 "=a" (__res) : "0" (__NR_##name), \
1406 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \
1407 "g" ((long)(arg4)) : "r10", "r11", "rcx", "memory"); \
1408 LSS_RETURN(type, __res); \
1409 }
1410 #undef _syscall5
1411 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1412 type5,arg5) \
1413 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1414 type5 arg5) { \
1415 long __res; \
1416 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; syscall" : \
1417 "=a" (__res) : "0" (__NR_##name), \
1418 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \
1419 "g" ((long)(arg4)), "g" ((long)(arg5)) : \
1420 "r8", "r10", "r11", "rcx", "memory"); \
1421 LSS_RETURN(type, __res); \
1422 }
1423 #undef _syscall6
1424 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1425 type5,arg5,type6,arg6) \
1426 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1427 type5 arg5, type6 arg6) { \
1428 long __res; \
1429 __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; movq %7,%%r9;" \
1430 "syscall" : \
1431 "=a" (__res) : "0" (__NR_##name), \
1432 "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \
1433 "g" ((long)(arg4)), "g" ((long)(arg5)), "g" ((long)(arg6)) : \
1434 "r8", "r9", "r10", "r11", "rcx", "memory"); \
1435 LSS_RETURN(type, __res); \
1436 }
1437 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
1438 int flags, void *arg, int *parent_tidptr,
1439 void *newtls, int *child_tidptr) {
1440 long __res;
1441 {
1442 register void *__tls __asm__("r8") = newtls;
1443 register int *__ctid __asm__("r10") = child_tidptr;
1444 __asm__ __volatile__(/* if (fn == NULL)
1445 * return -EINVAL;
1446 */
1447 "testq %4,%4\n"
1448 "jz 1f\n"
1449
1450 /* if (child_stack == NULL)
1451 * return -EINVAL;
1452 */
1453 "testq %5,%5\n"
1454 "jz 1f\n"
1455
1456 /* childstack -= 2*sizeof(void *);
1457 */
1458 "subq $16,%5\n"
1459
1460 /* Push "arg" and "fn" onto the stack that will be
1461 * used by the child.
1462 */
1463 "movq %7,8(%5)\n"
1464 "movq %4,0(%5)\n"
1465
1466 /* %rax = syscall(%rax = __NR_clone,
1467 * %rdi = flags,
1468 * %rsi = child_stack,
1469 * %rdx = parent_tidptr,
1470 * %r8 = new_tls,
1471 * %r10 = child_tidptr)
1472 */
1473 "movq %2,%%rax\n"
1474 "syscall\n"
1475
1476 /* if (%rax != 0)
1477 * return;
1478 */
1479 "testq %%rax,%%rax\n"
1480 "jnz 1f\n"
1481
1482 /* In the child. Terminate frame pointer chain.
1483 */
1484 "xorq %%rbp,%%rbp\n"
1485
1486 /* Call "fn(arg)".
1487 */
1488 "popq %%rax\n"
1489 "popq %%rdi\n"
1490 "call *%%rax\n"
1491
1492 /* Call _exit(%ebx).
1493 */
1494 "movq %%rax,%%rdi\n"
1495 "movq %3,%%rax\n"
1496 "syscall\n"
1497
1498 /* Return to parent.
1499 */
1500 "1:\n"
1501 : "=a" (__res)
1502 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
1503 "r"(fn), "S"(child_stack), "D"(flags), "r"(arg),
1504 "d"(parent_tidptr), "r"(__tls), "r"(__ctid)
1505 : "memory", "r11", "rcx");
1506 }
1507 LSS_RETURN(int, __res);
1508 }
1509 LSS_INLINE _syscall4(int, fadvise64, int, fd, loff_t, offset, loff_t, len,
1510 int, advice)
1511
1512 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
1513 /* On x86-64, the kernel does not know how to return from
1514 * a signal handler. Instead, it relies on user space to provide a
1515 * restorer function that calls the rt_sigreturn() system call.
1516 * Unfortunately, we cannot just reference the glibc version of this
1517 * function, as glibc goes out of its way to make it inaccessible.
1518 */
1519 void (*res)(void);
1520 __asm__ __volatile__("call 2f\n"
1521 "0:.align 16\n"
1522 "1:movq %1,%%rax\n"
1523 "syscall\n"
1524 "2:popq %0\n"
1525 "addq $(1b-0b),%0\n"
1526 : "=a" (res)
1527 : "i" (__NR_rt_sigreturn));
1528 return res;
1529 }
1530 #elif defined(__ARM_ARCH_3__)
1531 #undef LSS_REG
1532 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
1533 #undef LSS_BODY
1534 #define LSS_BODY(type,name,args...) \
1535 register long __res_r0 __asm__("r0"); \
1536 long __res; \
1537 __asm__ __volatile__ (__syscall(name) \
1538 : "=r"(__res_r0) : args : "lr", "memory"); \
1539 __res = __res_r0; \
1540 LSS_RETURN(type, __res)
1541 #undef _syscall0
1542 #define _syscall0(type, name) \
1543 type LSS_NAME(name)() { \
1544 LSS_BODY(type, name); \
1545 }
1546 #undef _syscall1
1547 #define _syscall1(type, name, type1, arg1) \
1548 type LSS_NAME(name)(type1 arg1) { \
1549 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
1550 }
1551 #undef _syscall2
1552 #define _syscall2(type, name, type1, arg1, type2, arg2) \
1553 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
1554 LSS_REG(0, arg1); LSS_REG(1, arg2); \
1555 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
1556 }
1557 #undef _syscall3
1558 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
1559 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
1560 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
1561 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
1562 }
1563 #undef _syscall4
1564 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
1565 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
1566 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
1567 LSS_REG(3, arg4); \
1568 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
1569 }
1570 #undef _syscall5
1571 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1572 type5,arg5) \
1573 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1574 type5 arg5) { \
1575 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
1576 LSS_REG(3, arg4); LSS_REG(4, arg5); \
1577 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
1578 "r"(__r4)); \
1579 }
1580 #undef _syscall6
1581 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1582 type5,arg5,type6,arg6) \
1583 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1584 type5 arg5, type6 arg6) { \
1585 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
1586 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
1587 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
1588 "r"(__r4), "r"(__r5)); \
1589 }
1590 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
1591 int flags, void *arg, int *parent_tidptr,
1592 void *newtls, int *child_tidptr) {
1593 long __res;
1594 {
1595 register int __flags __asm__("r0") = flags;
1596 register void *__stack __asm__("r1") = child_stack;
1597 register void *__ptid __asm__("r2") = parent_tidptr;
1598 register void *__tls __asm__("r3") = newtls;
1599 register int *__ctid __asm__("r4") = child_tidptr;
1600 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
1601 * return -EINVAL;
1602 */
1603 "cmp %2,#0\n"
1604 "cmpne %3,#0\n"
1605 "moveq %0,%1\n"
1606 "beq 1f\n"
1607
1608 /* Push "arg" and "fn" onto the stack that will be
1609 * used by the child.
1610 */
1611 "str %5,[%3,#-4]!\n"
1612 "str %2,[%3,#-4]!\n"
1613
1614 /* %r0 = syscall(%r0 = flags,
1615 * %r1 = child_stack,
1616 * %r2 = parent_tidptr,
1617 * %r3 = newtls,
1618 * %r4 = child_tidptr)
1619 */
1620 __syscall(clone)"\n"
1621
1622 /* if (%r0 != 0)
1623 * return %r0;
1624 */
1625 "movs %0,r0\n"
1626 "bne 1f\n"
1627
1628 /* In the child, now. Call "fn(arg)".
1629 */
1630 "ldr r0,[sp, #4]\n"
1631 "mov lr,pc\n"
1632 "ldr pc,[sp]\n"
1633
1634 /* Call _exit(%r0).
1635 */
1636 __syscall(exit)"\n"
1637 "1:\n"
1638 : "=r" (__res)
1639 : "i"(-EINVAL),
1640 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
1641 "r"(__ptid), "r"(__tls), "r"(__ctid)
1642 : "lr", "memory");
1643 }
1644 LSS_RETURN(int, __res);
1645 }
1646 #elif defined(__ARM_EABI__)
1647 /* Most definitions of _syscallX() neglect to mark "memory" as being
1648 * clobbered. This causes problems with compilers, that do a better job
1649 * at optimizing across __asm__ calls.
1650 * So, we just have to redefine all fo the _syscallX() macros.
1651 */
1652 #undef LSS_REG
1653 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
1654 #undef LSS_BODY
1655 #define LSS_BODY(type,name,args...) \
1656 register long __res_r0 __asm__("r0"); \
1657 long __res; \
1658 __asm__ __volatile__ ("push {r7}\n" \
1659 "mov r7, %1\n" \
1660 "swi 0x0\n" \
1661 "pop {r7}\n" \
1662 : "=r"(__res_r0) \
1663 : "i"(__NR_##name) , ## args \
1664 : "lr", "memory"); \
1665 __res = __res_r0; \
1666 LSS_RETURN(type, __res)
1667 #undef _syscall0
1668 #define _syscall0(type, name) \
1669 type LSS_NAME(name)() { \
1670 LSS_BODY(type, name); \
1671 }
1672 #undef _syscall1
1673 #define _syscall1(type, name, type1, arg1) \
1674 type LSS_NAME(name)(type1 arg1) { \
1675 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
1676 }
1677 #undef _syscall2
1678 #define _syscall2(type, name, type1, arg1, type2, arg2) \
1679 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
1680 LSS_REG(0, arg1); LSS_REG(1, arg2); \
1681 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
1682 }
1683 #undef _syscall3
1684 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
1685 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
1686 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
1687 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
1688 }
1689 #undef _syscall4
1690 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
1691 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
1692 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
1693 LSS_REG(3, arg4); \
1694 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
1695 }
1696 #undef _syscall5
1697 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1698 type5,arg5) \
1699 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1700 type5 arg5) { \
1701 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
1702 LSS_REG(3, arg4); LSS_REG(4, arg5); \
1703 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
1704 "r"(__r4)); \
1705 }
1706 #undef _syscall6
1707 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1708 type5,arg5,type6,arg6) \
1709 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1710 type5 arg5, type6 arg6) { \
1711 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
1712 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
1713 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
1714 "r"(__r4), "r"(__r5)); \
1715 }
1716 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
1717 int flags, void *arg, int *parent_tidptr,
1718 void *newtls, int *child_tidptr) {
1719 long __res;
1720 {
1721 register int __flags __asm__("r0") = flags;
1722 register void *__stack __asm__("r1") = child_stack;
1723 register void *__ptid __asm__("r2") = parent_tidptr;
1724 register void *__tls __asm__("r3") = newtls;
1725 register int *__ctid __asm__("r4") = child_tidptr;
1726 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
1727 * return -EINVAL;
1728 */
1729 "cmp %2,#0\n"
1730 "cmpne %3,#0\n"
1731 "moveq %0,%1\n"
1732 "beq 1f\n"
1733
1734 /* Push "arg" and "fn" onto the stack that will be
1735 * used by the child.
1736 */
1737 "str %5,[%3,#-4]!\n"
1738 "str %2,[%3,#-4]!\n"
1739
1740 /* %r0 = syscall(%r0 = flags,
1741 * %r1 = child_stack,
1742 * %r2 = parent_tidptr,
1743 * %r3 = newtls,
1744 * %r4 = child_tidptr)
1745 */
1746 "mov r7, %9\n"
1747 "swi 0x0\n"
1748
1749 /* if (%r0 != 0)
1750 * return %r0;
1751 */
1752 "movs %0,r0\n"
1753 "bne 1f\n"
1754
1755 /* In the child, now. Call "fn(arg)".
1756 */
1757 "ldr r0,[sp, #4]\n"
1758 "mov lr,pc\n"
1759 "ldr pc,[sp]\n"
1760
1761 /* Call _exit(%r0).
1762 */
1763 "mov r7, %10\n"
1764 "swi 0x0\n"
1765 "1:\n"
1766 : "=r" (__res)
1767 : "i"(-EINVAL),
1768 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
1769 "r"(__ptid), "r"(__tls), "r"(__ctid),
1770 "i"(__NR_clone), "i"(__NR_exit)
1771 : "lr", "memory");
1772 }
1773 LSS_RETURN(int, __res);
1774 }
1775 #elif defined(__mips__)
1776 #undef LSS_REG
1777 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
1778 (unsigned long)(a)
1779 #undef LSS_BODY
1780 #define LSS_BODY(type,name,r7,...) \
1781 register unsigned long __v0 __asm__("$2") = __NR_##name; \
1782 __asm__ __volatile__ ("syscall\n" \
1783 : "=&r"(__v0), r7 (__r7) \
1784 : "0"(__v0), ##__VA_ARGS__ \
1785 : "$8", "$9", "$10", "$11", "$12", \
1786 "$13", "$14", "$15", "$24", "memory"); \
1787 LSS_RETURN(type, __v0, __r7)
1788 #undef _syscall0
1789 #define _syscall0(type, name) \
1790 type LSS_NAME(name)() { \
1791 register unsigned long __r7 __asm__("$7"); \
1792 LSS_BODY(type, name, "=r"); \
1793 }
1794 #undef _syscall1
1795 #define _syscall1(type, name, type1, arg1) \
1796 type LSS_NAME(name)(type1 arg1) { \
1797 register unsigned long __r7 __asm__("$7"); \
1798 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \
1799 }
1800 #undef _syscall2
1801 #define _syscall2(type, name, type1, arg1, type2, arg2) \
1802 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
1803 register unsigned long __r7 __asm__("$7"); \
1804 LSS_REG(4, arg1); LSS_REG(5, arg2); \
1805 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \
1806 }
1807 #undef _syscall3
1808 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
1809 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
1810 register unsigned long __r7 __asm__("$7"); \
1811 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1812 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \
1813 }
1814 #undef _syscall4
1815 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
1816 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
1817 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1818 LSS_REG(7, arg4); \
1819 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \
1820 }
1821 #undef _syscall5
1822 #if _MIPS_SIM == _MIPS_SIM_ABI32
1823 /* The old 32bit MIPS system call API passes the fifth and sixth argument
1824 * on the stack, whereas the new APIs use registers "r8" and "r9".
1825 */
1826 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1827 type5,arg5) \
1828 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1829 type5 arg5) { \
1830 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1831 LSS_REG(7, arg4); \
1832 register unsigned long __v0 __asm__("$2"); \
1833 __asm__ __volatile__ (".set noreorder\n" \
1834 "lw $2, %6\n" \
1835 "subu $29, 32\n" \
1836 "sw $2, 16($29)\n" \
1837 "li $2, %2\n" \
1838 "syscall\n" \
1839 "addiu $29, 32\n" \
1840 ".set reorder\n" \
1841 : "=&r"(__v0), "+r" (__r7) \
1842 : "i" (__NR_##name), "r"(__r4), "r"(__r5), \
1843 "r"(__r6), "m" ((unsigned long)arg5) \
1844 : "$8", "$9", "$10", "$11", "$12", \
1845 "$13", "$14", "$15", "$24", "memory"); \
1846 LSS_RETURN(type, __v0, __r7); \
1847 }
1848 #else
1849 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1850 type5,arg5) \
1851 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1852 type5 arg5) { \
1853 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1854 LSS_REG(7, arg4); LSS_REG(8, arg5); \
1855 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
1856 "r"(__r8)); \
1857 }
1858 #endif
1859 #undef _syscall6
1860 #if _MIPS_SIM == _MIPS_SIM_ABI32
1861 /* The old 32bit MIPS system call API passes the fifth and sixth argument
1862 * on the stack, whereas the new APIs use registers "r8" and "r9".
1863 */
1864 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1865 type5,arg5,type6,arg6) \
1866 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1867 type5 arg5, type6 arg6) { \
1868 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1869 LSS_REG(7, arg4); \
1870 register unsigned long __v0 __asm__("$2"); \
1871 __asm__ __volatile__ (".set noreorder\n" \
1872 "lw $2, %6\n" \
1873 "lw $8, %7\n" \
1874 "subu $29, 32\n" \
1875 "sw $2, 16($29)\n" \
1876 "sw $8, 20($29)\n" \
1877 "li $2, %2\n" \
1878 "syscall\n" \
1879 "addiu $29, 32\n" \
1880 ".set reorder\n" \
1881 : "=&r"(__v0), "+r" (__r7) \
1882 : "i" (__NR_##name), "r"(__r4), "r"(__r5), \
1883 "r"(__r6), "r" ((unsigned long)arg5), \
1884 "r" ((unsigned long)arg6) \
1885 : "$8", "$9", "$10", "$11", "$12", \
1886 "$13", "$14", "$15", "$24", "memory"); \
1887 LSS_RETURN(type, __v0, __r7); \
1888 }
1889 #else
1890 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1891 type5,arg5,type6,arg6) \
1892 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1893 type5 arg5,type6 arg6) { \
1894 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1895 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \
1896 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
1897 "r"(__r8), "r"(__r9)); \
1898 }
1899 #endif
1900 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
1901 int flags, void *arg, int *parent_tidptr,
1902 void *newtls, int *child_tidptr) {
1903 register unsigned long __v0 __asm__("$2");
1904 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
1905 {
1906 register int __flags __asm__("$4") = flags;
1907 register void *__stack __asm__("$5") = child_stack;
1908 register void *__ptid __asm__("$6") = parent_tidptr;
1909 register int *__ctid __asm__("$8") = child_tidptr;
1910 __asm__ __volatile__(
1911 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
1912 "subu $29,24\n"
1913 #elif _MIPS_SIM == _MIPS_SIM_NABI32
1914 "sub $29,16\n"
1915 #else
1916 "dsubu $29,16\n"
1917 #endif
1918
1919 /* if (fn == NULL || child_stack == NULL)
1920 * return -EINVAL;
1921 */
1922 "li %0,%2\n"
1923 "beqz %5,1f\n"
1924 "beqz %6,1f\n"
1925
1926 /* Push "arg" and "fn" onto the stack that will be
1927 * used by the child.
1928 */
1929 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
1930 "subu %6,32\n"
1931 "sw %5,0(%6)\n"
1932 "sw %8,4(%6)\n"
1933 #elif _MIPS_SIM == _MIPS_SIM_NABI32
1934 "sub %6,32\n"
1935 "sw %5,0(%6)\n"
1936 "sw %8,8(%6)\n"
1937 #else
1938 "dsubu %6,32\n"
1939 "sd %5,0(%6)\n"
1940 "sd %8,8(%6)\n"
1941 #endif
1942
1943 /* $7 = syscall($4 = flags,
1944 * $5 = child_stack,
1945 * $6 = parent_tidptr,
1946 * $7 = newtls,
1947 * $8 = child_tidptr)
1948 */
1949 "li $2,%3\n"
1950 "syscall\n"
1951
1952 /* if ($7 != 0)
1953 * return $2;
1954 */
1955 "bnez $7,1f\n"
1956 "bnez $2,1f\n"
1957
1958 /* In the child, now. Call "fn(arg)".
1959 */
1960 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
1961 "lw $25,0($29)\n"
1962 "lw $4,4($29)\n"
1963 #elif _MIPS_SIM == _MIPS_SIM_NABI32
1964 "lw $25,0($29)\n"
1965 "lw $4,8($29)\n"
1966 #else
1967 "ld $25,0($29)\n"
1968 "ld $4,8($29)\n"
1969 #endif
1970 "jalr $25\n"
1971
1972 /* Call _exit($2)
1973 */
1974 "move $4,$2\n"
1975 "li $2,%4\n"
1976 "syscall\n"
1977
1978 "1:\n"
1979 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
1980 "addu $29, 24\n"
1981 #elif _MIPS_SIM == _MIPS_SIM_NABI32
1982 "add $29, 16\n"
1983 #else
1984 "daddu $29,16\n"
1985 #endif
1986 : "=&r" (__v0), "=r" (__r7)
1987 : "i"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
1988 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
1989 "r"(__ptid), "r"(__r7), "r"(__ctid)
1990 : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
1991 "$24", "memory");
1992 }
1993 LSS_RETURN(int, __v0, __r7);
1994 }
1995 #elif defined (__PPC__)
1996 #undef LSS_LOADARGS_0
1997 #define LSS_LOADARGS_0(name, dummy...) \
1998 __sc_0 = __NR_##name
1999 #undef LSS_LOADARGS_1
2000 #define LSS_LOADARGS_1(name, arg1) \
2001 LSS_LOADARGS_0(name); \
2002 __sc_3 = (unsigned long) (arg1)
2003 #undef LSS_LOADARGS_2
2004 #define LSS_LOADARGS_2(name, arg1, arg2) \
2005 LSS_LOADARGS_1(name, arg1); \
2006 __sc_4 = (unsigned long) (arg2)
2007 #undef LSS_LOADARGS_3
2008 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \
2009 LSS_LOADARGS_2(name, arg1, arg2); \
2010 __sc_5 = (unsigned long) (arg3)
2011 #undef LSS_LOADARGS_4
2012 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \
2013 LSS_LOADARGS_3(name, arg1, arg2, arg3); \
2014 __sc_6 = (unsigned long) (arg4)
2015 #undef LSS_LOADARGS_5
2016 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
2017 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \
2018 __sc_7 = (unsigned long) (arg5)
2019 #undef LSS_LOADARGS_6
2020 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
2021 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
2022 __sc_8 = (unsigned long) (arg6)
2023 #undef LSS_ASMINPUT_0
2024 #define LSS_ASMINPUT_0 "0" (__sc_0)
2025 #undef LSS_ASMINPUT_1
2026 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
2027 #undef LSS_ASMINPUT_2
2028 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
2029 #undef LSS_ASMINPUT_3
2030 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
2031 #undef LSS_ASMINPUT_4
2032 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
2033 #undef LSS_ASMINPUT_5
2034 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
2035 #undef LSS_ASMINPUT_6
2036 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
2037 #undef LSS_BODY
2038 #define LSS_BODY(nr, type, name, args...) \
2039 long __sc_ret, __sc_err; \
2040 { \
2041 register unsigned long __sc_0 __asm__ ("r0"); \
2042 register unsigned long __sc_3 __asm__ ("r3"); \
2043 register unsigned long __sc_4 __asm__ ("r4"); \
2044 register unsigned long __sc_5 __asm__ ("r5"); \
2045 register unsigned long __sc_6 __asm__ ("r6"); \
2046 register unsigned long __sc_7 __asm__ ("r7"); \
2047 register unsigned long __sc_8 __asm__ ("r8"); \
2048 \
2049 LSS_LOADARGS_##nr(name, args); \
2050 __asm__ __volatile__ \
2051 ("sc\n\t" \
2052 "mfcr %0" \
2053 : "=&r" (__sc_0), \
2054 "=&r" (__sc_3), "=&r" (__sc_4), \
2055 "=&r" (__sc_5), "=&r" (__sc_6), \
2056 "=&r" (__sc_7), "=&r" (__sc_8) \
2057 : LSS_ASMINPUT_##nr \
2058 : "cr0", "ctr", "memory", \
2059 "r9", "r10", "r11", "r12"); \
2060 __sc_ret = __sc_3; \
2061 __sc_err = __sc_0; \
2062 } \
2063 LSS_RETURN(type, __sc_ret, __sc_err)
2064 #undef _syscall0
2065 #define _syscall0(type, name) \
2066 type LSS_NAME(name)(void) { \
2067 LSS_BODY(0, type, name); \
2068 }
2069 #undef _syscall1
2070 #define _syscall1(type, name, type1, arg1) \
2071 type LSS_NAME(name)(type1 arg1) { \
2072 LSS_BODY(1, type, name, arg1); \
2073 }
2074 #undef _syscall2
2075 #define _syscall2(type, name, type1, arg1, type2, arg2) \
2076 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
2077 LSS_BODY(2, type, name, arg1, arg2); \
2078 }
2079 #undef _syscall3
2080 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
2081 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
2082 LSS_BODY(3, type, name, arg1, arg2, arg3); \
2083 }
2084 #undef _syscall4
2085 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
2086 type4, arg4) \
2087 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2088 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \
2089 }
2090 #undef _syscall5
2091 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
2092 type4, arg4, type5, arg5) \
2093 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2094 type5 arg5) { \
2095 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \
2096 }
2097 #undef _syscall6
2098 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
2099 type4, arg4, type5, arg5, type6, arg6) \
2100 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2101 type5 arg5, type6 arg6) { \
2102 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
2103 }
2104 /* clone function adapted from glibc 2.3.6 clone.S */
2105 /* TODO(csilvers): consider wrapping some args up in a struct, like we
2106 * do for i386's _syscall6, so we can compile successfully on gcc 2.95
2107 */
2108 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2109 int flags, void *arg, int *parent_tidptr,
2110 void *newtls, int *child_tidptr) {
2111 long __ret, __err;
2112 {
2113 register int (*__fn)(void *) __asm__ ("r8") = fn;
2114 register void *__cstack __asm__ ("r4") = child_stack;
2115 register int __flags __asm__ ("r3") = flags;
2116 register void * __arg __asm__ ("r9") = arg;
2117 register int * __ptidptr __asm__ ("r5") = parent_tidptr;
2118 register void * __newtls __asm__ ("r6") = newtls;
2119 register int * __ctidptr __asm__ ("r7") = child_tidptr;
2120 __asm__ __volatile__(
2121 /* check for fn == NULL
2122 * and child_stack == NULL
2123 */
2124 "cmpwi cr0, %6, 0\n\t"
2125 "cmpwi cr1, %7, 0\n\t"
2126 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
2127 "beq- cr0, 1f\n\t"
2128
2129 /* set up stack frame for child */
2130 "clrrwi %7, %7, 4\n\t"
2131 "li 0, 0\n\t"
2132 "stwu 0, -16(%7)\n\t"
2133
2134 /* fn, arg, child_stack are saved across the syscall: r28-30 */
2135 "mr 28, %6\n\t"
2136 "mr 29, %7\n\t"
2137 "mr 27, %9\n\t"
2138
2139 /* syscall */
2140 "li 0, %4\n\t"
2141 /* flags already in r3
2142 * child_stack already in r4
2143 * ptidptr already in r5
2144 * newtls already in r6
2145 * ctidptr already in r7
2146 */
2147 "sc\n\t"
2148
2149 /* Test if syscall was successful */
2150 "cmpwi cr1, 3, 0\n\t"
2151 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
2152 "bne- cr1, 1f\n\t"
2153
2154 /* Do the function call */
2155 "mtctr 28\n\t"
2156 "mr 3, 27\n\t"
2157 "bctrl\n\t"
2158
2159 /* Call _exit(r3) */
2160 "li 0, %5\n\t"
2161 "sc\n\t"
2162
2163 /* Return to parent */
2164 "1:\n"
2165 "mfcr %1\n\t"
2166 "mr %0, 3\n\t"
2167 : "=r" (__ret), "=r" (__err)
2168 : "0" (-1), "1" (EINVAL),
2169 "i" (__NR_clone), "i" (__NR_exit),
2170 "r" (__fn), "r" (__cstack), "r" (__flags),
2171 "r" (__arg), "r" (__ptidptr), "r" (__newtls),
2172 "r" (__ctidptr)
2173 : "cr0", "cr1", "memory", "ctr",
2174 "r0", "r29", "r27", "r28");
2175 }
2176 LSS_RETURN(int, __ret, __err);
2177 }
2178 #endif
2179 #define __NR__exit __NR_exit
2180 #define __NR__gettid __NR_gettid
2181 #define __NR__mremap __NR_mremap
2182 LSS_INLINE _syscall1(int, chdir, const char *,p)
2183 LSS_INLINE _syscall1(int, close, int, f)
2184 LSS_INLINE _syscall1(int, dup, int, f)
2185 LSS_INLINE _syscall2(int, dup2, int, s,
2186 int, d)
2187 LSS_INLINE _syscall3(int, execve, const char*, f,
2188 const char*const*,a,const char*const*, e)
2189 LSS_INLINE _syscall1(int, _exit, int, e)
2190 LSS_INLINE _syscall3(int, fcntl, int, f,
2191 int, c, long, a)
2192 LSS_INLINE _syscall0(pid_t, fork)
2193 LSS_INLINE _syscall2(int, fstat, int, f,
2194 struct kernel_stat*, b)
2195 LSS_INLINE _syscall2(int, fstatfs, int, f,
2196 struct kernel_statfs*, b)
2197 LSS_INLINE _syscall4(int, futex, int*, a,
2198 int, o, int, v,
2199 struct kernel_timespec*, t)
2200 LSS_INLINE _syscall3(int, getdents, int, f,
2201 struct kernel_dirent*, d, int, c)
2202 LSS_INLINE _syscall3(int, getdents64, int, f,
2203 struct kernel_dirent64*, d, int, c)
2204 LSS_INLINE _syscall0(gid_t, getegid)
2205 LSS_INLINE _syscall0(uid_t, geteuid)
2206 LSS_INLINE _syscall0(pid_t, getpgrp)
2207 LSS_INLINE _syscall0(pid_t, getpid)
2208 LSS_INLINE _syscall0(pid_t, getppid)
2209 LSS_INLINE _syscall2(int, getpriority, int, a,
2210 int, b)
2211 #if !defined(__ARM_EABI__)
2212 LSS_INLINE _syscall2(int, getrlimit, int, r,
2213 struct kernel_rlimit*, l)
2214 #endif
2215 LSS_INLINE _syscall1(pid_t, getsid, pid_t, p)
2216 LSS_INLINE _syscall0(pid_t, _gettid)
2217 LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t,
2218 void*, tz)
2219 LSS_INLINE _syscall5(int, setxattr, const char *,p,
2220 const char *, n, const void *,v,
2221 size_t, s, int, f)
2222 LSS_INLINE _syscall5(int, lsetxattr, const char *,p,
2223 const char *, n, const void *,v,
2224 size_t, s, int, f)
2225 LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p,
2226 const char *, n, void *, v, size_t, s)
2227 LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p,
2228 const char *, n, void *, v, size_t, s)
2229 LSS_INLINE _syscall2(int, kill, pid_t, p,
2230 int, s)
2231 LSS_INLINE _syscall3(off_t, lseek, int, f,
2232 off_t, o, int, w)
2233 LSS_INLINE _syscall2(int, munmap, void*, s,
2234 size_t, l)
2235 LSS_INLINE _syscall6(long, move_pages, pid_t, p,
2236 unsigned long, n, void **,g, int *, d,
2237 int *, s, int, f)
2238 LSS_INLINE _syscall5(void*, _mremap, void*, o,
2239 size_t, os, size_t, ns,
2240 unsigned long, f, void *, a)
2241 LSS_INLINE _syscall3(int, open, const char*, p,
2242 int, f, int, m)
2243 LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u,
2244 unsigned int, n, int, t)
2245 LSS_INLINE _syscall2(int, prctl, int, o,
2246 long, a)
2247 LSS_INLINE _syscall4(long, ptrace, int, r,
2248 pid_t, p, void *, a, void *, d)
2249 LSS_INLINE _syscall3(ssize_t, read, int, f,
2250 void *, b, size_t, c)
2251 LSS_INLINE _syscall3(int, readlink, const char*, p,
2252 char*, b, size_t, s)
2253 LSS_INLINE _syscall4(int, rt_sigaction, int, s,
2254 const struct kernel_sigaction*, a,
2255 struct kernel_sigaction*, o, size_t, c)
2256 LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s,
2257 size_t, c)
2258 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h,
2259 const struct kernel_sigset_t*, s,
2260 struct kernel_sigset_t*, o, size_t, c)
2261 LSS_INLINE _syscall2(int, rt_sigsuspend,
2262 const struct kernel_sigset_t*, s, size_t, c)
2263 LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p,
2264 unsigned int, l, unsigned long *, m)
2265 LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p,
2266 unsigned int, l, unsigned long *, m)
2267 LSS_INLINE _syscall0(int, sched_yield)
2268 LSS_INLINE _syscall1(long, set_tid_address, int *, t)
2269 LSS_INLINE _syscall1(int, setfsgid, gid_t, g)
2270 LSS_INLINE _syscall1(int, setfsuid, uid_t, u)
2271 LSS_INLINE _syscall2(int, setpgid, pid_t, p,
2272 pid_t, g)
2273 LSS_INLINE _syscall3(int, setpriority, int, a,
2274 int, b, int, p)
2275 LSS_INLINE _syscall3(int, setresgid, gid_t, r,
2276 gid_t, e, gid_t, s)
2277 LSS_INLINE _syscall3(int, setresuid, uid_t, r,
2278 uid_t, e, uid_t, s)
2279 LSS_INLINE _syscall2(int, setrlimit, int, r,
2280 const struct kernel_rlimit*, l)
2281 LSS_INLINE _syscall0(pid_t, setsid)
2282 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
2283 const stack_t*, o)
2284 LSS_INLINE _syscall2(int, stat, const char*, f,
2285 struct kernel_stat*, b)
2286 LSS_INLINE _syscall2(int, statfs, const char*, f,
2287 struct kernel_statfs*, b)
2288 LSS_INLINE _syscall1(int, unlink, const char*, f)
2289 LSS_INLINE _syscall3(ssize_t, write, int, f,
2290 const void *, b, size_t, c)
2291 LSS_INLINE _syscall3(ssize_t, writev, int, f,
2292 const struct kernel_iovec*, v, size_t, c)
2293 #if defined(__x86_64__) || \
2294 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
2295 LSS_INLINE _syscall3(int, recvmsg, int, s,
2296 struct kernel_msghdr*, m, int, f)
2297 LSS_INLINE _syscall3(int, sendmsg, int, s,
2298 const struct kernel_msghdr*, m, int, f)
2299 LSS_INLINE _syscall6(int, sendto, int, s,
2300 const void*, m, size_t, l,
2301 int, f,
2302 const struct kernel_sockaddr*, a, int, t)
2303 LSS_INLINE _syscall2(int, shutdown, int, s,
2304 int, h)
2305 LSS_INLINE _syscall3(int, socket, int, d,
2306 int, t, int, p)
2307 LSS_INLINE _syscall4(int, socketpair, int, d,
2308 int, t, int, p, int*, s)
2309 #endif
2310 #if defined(__x86_64__)
2311 LSS_INLINE _syscall6(void*, mmap, void*, s,
2312 size_t, l, int, p,
2313 int, f, int, d,
2314 __off64_t, o)
2315 LSS_INLINE _syscall4(int, newfstatat, int, d,
2316 const char *, p,
2317 struct kernel_stat*, b, int, f)
2318
2319 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
2320 return LSS_NAME(setfsgid)(gid);
2321 }
2322
2323 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
2324 return LSS_NAME(setfsuid)(uid);
2325 }
2326
2327 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
2328 return LSS_NAME(setresgid)(rgid, egid, sgid);
2329 }
2330
2331 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
2332 return LSS_NAME(setresuid)(ruid, euid, suid);
2333 }
2334
2335 LSS_INLINE int LSS_NAME(sigaction)(int signum,
2336 const struct kernel_sigaction *act,
2337 struct kernel_sigaction *oldact) {
2338 /* On x86_64, the kernel requires us to always set our own
2339 * SA_RESTORER in order to be able to return from a signal handler.
2340 * This function must have a "magic" signature that the "gdb"
2341 * (and maybe the kernel?) can recognize.
2342 */
2343 if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
2344 struct kernel_sigaction a = *act;
2345 a.sa_flags |= SA_RESTORER;
2346 a.sa_restorer = LSS_NAME(restore_rt)();
2347 return LSS_NAME(rt_sigaction)(signum, &a, oldact,
2348 (KERNEL_NSIG+7)/8);
2349 } else {
2350 return LSS_NAME(rt_sigaction)(signum, act, oldact,
2351 (KERNEL_NSIG+7)/8);
2352 }
2353 }
2354
2355 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
2356 return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
2357 }
2358
2359 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
2360 const struct kernel_sigset_t *set,
2361 struct kernel_sigset_t *oldset) {
2362 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
2363 }
2364
2365 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
2366 return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
2367 }
2368 #endif
2369 #if defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
2370 defined(__ARM_EABI__) || \
2371 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
2372 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
2373 int*, s, int, o,
2374 struct kernel_rusage*, r)
2375
2376 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){
2377 return LSS_NAME(wait4)(pid, status, options, 0);
2378 }
2379 #endif
2380 #if defined(__i386__) || defined(__x86_64__)
2381 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
2382 LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)
2383 #endif
2384 #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__)
2385 #define __NR__setfsgid32 __NR_setfsgid32
2386 #define __NR__setfsuid32 __NR_setfsuid32
2387 #define __NR__setresgid32 __NR_setresgid32
2388 #define __NR__setresuid32 __NR_setresuid32
2389 #if defined(__ARM_EABI__)
2390 LSS_INLINE _syscall2(int, ugetrlimit, int, r,
2391 struct kernel_rlimit*, l)
2392 #endif
2393 LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f)
2394 LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f)
2395 LSS_INLINE _syscall3(int, _setresgid32, gid_t, r,
2396 gid_t, e, gid_t, s)
2397 LSS_INLINE _syscall3(int, _setresuid32, uid_t, r,
2398 uid_t, e, uid_t, s)
2399
2400 LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
2401 int rc;
2402 if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 &&
2403 LSS_ERRNO == ENOSYS) {
2404 if ((unsigned int)gid & ~0xFFFFu) {
2405 rc = EINVAL;
2406 } else {
2407 rc = LSS_NAME(setfsgid)(gid);
2408 }
2409 }
2410 return rc;
2411 }
2412
2413 LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
2414 int rc;
2415 if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 &&
2416 LSS_ERRNO == ENOSYS) {
2417 if ((unsigned int)uid & ~0xFFFFu) {
2418 rc = EINVAL;
2419 } else {
2420 rc = LSS_NAME(setfsuid)(uid);
2421 }
2422 }
2423 return rc;
2424 }
2425
2426 LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
2427 int rc;
2428 if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 &&
2429 LSS_ERRNO == ENOSYS) {
2430 if ((unsigned int)rgid & ~0xFFFFu ||
2431 (unsigned int)egid & ~0xFFFFu ||
2432 (unsigned int)sgid & ~0xFFFFu) {
2433 rc = EINVAL;
2434 } else {
2435 rc = LSS_NAME(setresgid)(rgid, egid, sgid);
2436 }
2437 }
2438 return rc;
2439 }
2440
2441 LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
2442 int rc;
2443 if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 &&
2444 LSS_ERRNO == ENOSYS) {
2445 if ((unsigned int)ruid & ~0xFFFFu ||
2446 (unsigned int)euid & ~0xFFFFu ||
2447 (unsigned int)suid & ~0xFFFFu) {
2448 rc = EINVAL;
2449 } else {
2450 rc = LSS_NAME(setresuid)(ruid, euid, suid);
2451 }
2452 }
2453 return rc;
2454 }
2455 #endif
2456 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
2457 memset(&set->sig, 0, sizeof(set->sig));
2458 return 0;
2459 }
2460
2461 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
2462 memset(&set->sig, -1, sizeof(set->sig));
2463 return 0;
2464 }
2465
2466 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
2467 int signum) {
2468 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
2469 LSS_ERRNO = EINVAL;
2470 return -1;
2471 } else {
2472 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
2473 |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0])));
2474 return 0;
2475 }
2476 }
2477
2478 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
2479 int signum) {
2480 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
2481 LSS_ERRNO = EINVAL;
2482 return -1;
2483 } else {
2484 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
2485 &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0]))));
2486 return 0;
2487 }
2488 }
2489
2490 LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set,
2491 int signum) {
2492 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
2493 LSS_ERRNO = EINVAL;
2494 return -1;
2495 } else {
2496 return !!(set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] &
2497 (1UL << ((signum - 1) % (8*sizeof(set->sig[0])))));
2498 }
2499 }
2500 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
2501 defined(__ARM_EABI__) || \
2502 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || defined(__PPC__)
2503 #define __NR__sigaction __NR_sigaction
2504 #define __NR__sigpending __NR_sigpending
2505 #define __NR__sigprocmask __NR_sigprocmask
2506 #define __NR__sigsuspend __NR_sigsuspend
2507 #define __NR__socketcall __NR_socketcall
2508 LSS_INLINE _syscall2(int, fstat64, int, f,
2509 struct kernel_stat64 *, b)
2510 LSS_INLINE _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
2511 loff_t *, res, uint, wh)
2512 #if !defined(__ARM_EABI__)
2513 LSS_INLINE _syscall1(void*, mmap, void*, a)
2514 #endif
2515 LSS_INLINE _syscall6(void*, mmap2, void*, s,
2516 size_t, l, int, p,
2517 int, f, int, d,
2518 __off64_t, o)
2519 LSS_INLINE _syscall3(int, _sigaction, int, s,
2520 const struct kernel_old_sigaction*, a,
2521 struct kernel_old_sigaction*, o)
2522 LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s)
2523 LSS_INLINE _syscall3(int, _sigprocmask, int, h,
2524 const unsigned long*, s,
2525 unsigned long*, o)
2526 #ifdef __PPC__
2527 LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s)
2528 #else
2529 LSS_INLINE _syscall3(int, _sigsuspend, const void*, a,
2530 int, b,
2531 unsigned long, s)
2532 #endif
2533 LSS_INLINE _syscall2(int, stat64, const char *, p,
2534 struct kernel_stat64 *, b)
2535
2536 LSS_INLINE int LSS_NAME(sigaction)(int signum,
2537 const struct kernel_sigaction *act,
2538 struct kernel_sigaction *oldact) {
2539 int old_errno = LSS_ERRNO;
2540 int rc;
2541 struct kernel_sigaction a;
2542 if (act != NULL) {
2543 a = *act;
2544 #ifdef __i386__
2545 /* On i386, the kernel requires us to always set our own
2546 * SA_RESTORER when using realtime signals. Otherwise, it does not
2547 * know how to return from a signal handler. This function must have
2548 * a "magic" signature that the "gdb" (and maybe the kernel?) can
2549 * recognize.
2550 * Apparently, a SA_RESTORER is implicitly set by the kernel, when
2551 * using non-realtime signals.
2552 *
2553 * TODO: Test whether ARM needs a restorer
2554 */
2555 if (!(a.sa_flags & SA_RESTORER)) {
2556 a.sa_flags |= SA_RESTORER;
2557 a.sa_restorer = (a.sa_flags & SA_SIGINFO)
2558 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
2559 }
2560 #endif
2561 }
2562 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
2563 (KERNEL_NSIG+7)/8);
2564 if (rc < 0 && LSS_ERRNO == ENOSYS) {
2565 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
2566 if (!act) {
2567 ptr_a = NULL;
2568 } else {
2569 oa.sa_handler_ = act->sa_handler_;
2570 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
2571 #ifndef __mips__
2572 oa.sa_restorer = act->sa_restorer;
2573 #endif
2574 oa.sa_flags = act->sa_flags;
2575 }
2576 if (!oldact) {
2577 ptr_oa = NULL;
2578 }
2579 LSS_ERRNO = old_errno;
2580 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
2581 if (rc == 0 && oldact) {
2582 if (act) {
2583 memcpy(oldact, act, sizeof(*act));
2584 } else {
2585 memset(oldact, 0, sizeof(*oldact));
2586 }
2587 oldact->sa_handler_ = ptr_oa->sa_handler_;
2588 oldact->sa_flags = ptr_oa->sa_flags;
2589 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
2590 #ifndef __mips__
2591 oldact->sa_restorer = ptr_oa->sa_restorer;
2592 #endif
2593 }
2594 }
2595 return rc;
2596 }
2597
2598 LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {
2599 int old_errno = LSS_ERRNO;
2600 int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);
2601 if (rc < 0 && LSS_ERRNO == ENOSYS) {
2602 LSS_ERRNO = old_errno;
2603 LSS_NAME(sigemptyset)(set);
2604 rc = LSS_NAME(_sigpending)(&set->sig[0]);
2605 }
2606 return rc;
2607 }
2608
2609 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
2610 const struct kernel_sigset_t *set,
2611 struct kernel_sigset_t *oldset) {
2612 int olderrno = LSS_ERRNO;
2613 int rc = LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
2614 if (rc < 0 && LSS_ERRNO == ENOSYS) {
2615 LSS_ERRNO = olderrno;
2616 if (oldset) {
2617 LSS_NAME(sigemptyset)(oldset);
2618 }
2619 rc = LSS_NAME(_sigprocmask)(how,
2620 set ? &set->sig[0] : NULL,
2621 oldset ? &oldset->sig[0] : NULL);
2622 }
2623 return rc;
2624 }
2625
2626 LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {
2627 int olderrno = LSS_ERRNO;
2628 int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);
2629 if (rc < 0 && LSS_ERRNO == ENOSYS) {
2630 LSS_ERRNO = olderrno;
2631 rc = LSS_NAME(_sigsuspend)(
2632 #ifndef __PPC__
2633 set, 0,
2634 #endif
2635 set->sig[0]);
2636 }
2637 return rc;
2638 }
2639 #endif
2640 #if defined(__PPC__)
2641 #undef LSS_SC_LOADARGS_0
2642 #define LSS_SC_LOADARGS_0(dummy...)
2643 #undef LSS_SC_LOADARGS_1
2644 #define LSS_SC_LOADARGS_1(arg1) \
2645 __sc_4 = (unsigned long) (arg1)
2646 #undef LSS_SC_LOADARGS_2
2647 #define LSS_SC_LOADARGS_2(arg1, arg2) \
2648 LSS_SC_LOADARGS_1(arg1); \
2649 __sc_5 = (unsigned long) (arg2)
2650 #undef LSS_SC_LOADARGS_3
2651 #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \
2652 LSS_SC_LOADARGS_2(arg1, arg2); \
2653 __sc_6 = (unsigned long) (arg3)
2654 #undef LSS_SC_LOADARGS_4
2655 #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \
2656 LSS_SC_LOADARGS_3(arg1, arg2, arg3); \
2657 __sc_7 = (unsigned long) (arg4)
2658 #undef LSS_SC_LOADARGS_5
2659 #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \
2660 LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \
2661 __sc_8 = (unsigned long) (arg5)
2662 #undef LSS_SC_BODY
2663 #define LSS_SC_BODY(nr, type, opt, args...) \
2664 long __sc_ret, __sc_err; \
2665 { \
2666 register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \
2667 register unsigned long __sc_3 __asm__ ("r3") = opt; \
2668 register unsigned long __sc_4 __asm__ ("r4"); \
2669 register unsigned long __sc_5 __asm__ ("r5"); \
2670 register unsigned long __sc_6 __asm__ ("r6"); \
2671 register unsigned long __sc_7 __asm__ ("r7"); \
2672 register unsigned long __sc_8 __asm__ ("r8"); \
2673 LSS_SC_LOADARGS_##nr(args); \
2674 __asm__ __volatile__ \
2675 ("stwu 1, -48(1)\n\t" \
2676 "stw 4, 20(1)\n\t" \
2677 "stw 5, 24(1)\n\t" \
2678 "stw 6, 28(1)\n\t" \
2679 "stw 7, 32(1)\n\t" \
2680 "stw 8, 36(1)\n\t" \
2681 "addi 4, 1, 20\n\t" \
2682 "sc\n\t" \
2683 "mfcr %0" \
2684 : "=&r" (__sc_0), \
2685 "=&r" (__sc_3), "=&r" (__sc_4), \
2686 "=&r" (__sc_5), "=&r" (__sc_6), \
2687 "=&r" (__sc_7), "=&r" (__sc_8) \
2688 : LSS_ASMINPUT_##nr \
2689 : "cr0", "ctr", "memory"); \
2690 __sc_ret = __sc_3; \
2691 __sc_err = __sc_0; \
2692 } \
2693 LSS_RETURN(type, __sc_ret, __sc_err)
2694
2695 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
2696 int flags){
2697 LSS_SC_BODY(3, ssize_t, 17, s, msg, flags);
2698 }
2699
2700 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
2701 const struct kernel_msghdr *msg,
2702 int flags) {
2703 LSS_SC_BODY(3, ssize_t, 16, s, msg, flags);
2704 }
2705
2706 // TODO(csilvers): why is this ifdef'ed out?
2707 #if 0
2708 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
2709 int flags,
2710 const struct kernel_sockaddr *to,
2711 unsigned int tolen) {
2712 LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen);
2713 }
2714 #endif
2715
2716 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
2717 LSS_SC_BODY(2, int, 13, s, how);
2718 }
2719
2720 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
2721 LSS_SC_BODY(3, int, 1, domain, type, protocol);
2722 }
2723
2724 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
2725 int sv[2]) {
2726 LSS_SC_BODY(4, int, 8, d, type, protocol, sv);
2727 }
2728 #endif
2729 #if defined(__ARM_EABI__)
2730 LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg,
2731 int, flags);
2732 LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*,
2733 msg, int, flags);
2734 LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t, len,
2735 int, falgs, const struct kernel_sockaddr*, to,
2736 unsigned int, tolen);
2737 LSS_INLINE _syscall2(int, shutdown, int, s, int, how);
2738 LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol);
2739 LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol,
2740 int*, sv);
2741 #endif
2742 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
2743 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
2744 #define __NR__socketcall __NR_socketcall
2745 LSS_INLINE _syscall2(int, _socketcall, int, c,
2746 va_list, a)
2747 LSS_INLINE int LSS_NAME(socketcall)(int op, ...) {
2748 int rc;
2749 va_list ap;
2750 va_start(ap, op);
2751 rc = LSS_NAME(_socketcall)(op, ap);
2752 va_end(ap);
2753 return rc;
2754 }
2755 LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,
2756 int flags){
2757 return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags);
2758 }
2759 LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,
2760 const struct kernel_msghdr *msg,
2761 int flags) {
2762 return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags);
2763 }
2764 LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
2765 int flags,
2766 const struct kernel_sockaddr *to,
2767 unsigned int tolen) {
2768 return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen);
2769 }
2770 LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
2771 return LSS_NAME(socketcall)(13, s, how);
2772 }
2773 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
2774 return LSS_NAME(socketcall)(1, domain, type, protocol);
2775 }
2776
2777 LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
2778 int sv[2]) {
2779 return LSS_NAME(socketcall)(8, d, type, protocol, sv);
2780 }
2781 #endif
2782 #if defined(__i386__) || defined(__PPC__)
2783 LSS_INLINE _syscall4(int, fstatat64, int, d,
2784 const char *, p,
2785 struct kernel_stat64 *, b, int, f)
2786 #endif
2787 #if defined(__i386__) || defined(__PPC__) || \
2788 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
2789 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
2790 int*, s, int, o)
2791 #endif
2792 #if defined(__mips__)
2793 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
2794 * both file handles through CPU registers.
2795 */
2796 LSS_INLINE int LSS_NAME(pipe)(int *p) {
2797 register unsigned long __v0 __asm__("$2") = __NR_pipe;
2798 register unsigned long __v1 __asm__("$3");
2799 register unsigned long __r7 __asm__("$7");
2800 __asm__ __volatile__ ("syscall\n"
2801 : "=&r"(__v0), "=&r"(__v1), "+r" (__r7)
2802 : "0"(__v0)
2803 : "$8", "$9", "$10", "$11", "$12",
2804 "$13", "$14", "$15", "$24", "memory");
2805 if (__r7) {
2806 LSS_ERRNO = __v0;
2807 return -1;
2808 } else {
2809 p[0] = __v0;
2810 p[1] = __v1;
2811 return 0;
2812 }
2813 }
2814 #else
2815 LSS_INLINE _syscall1(int, pipe, int *, p)
2816 #endif
2817 /* TODO(csilvers): see if ppc can/should support this as well */
2818 #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
2819 defined(__ARM_EABI__) || \
2820 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)
2821 #define __NR__statfs64 __NR_statfs64
2822 #define __NR__fstatfs64 __NR_fstatfs64
2823 LSS_INLINE _syscall3(int, _statfs64, const char*, p,
2824 size_t, s,struct kernel_statfs64*, b)
2825 LSS_INLINE _syscall3(int, _fstatfs64, int, f,
2826 size_t, s,struct kernel_statfs64*, b)
2827 LSS_INLINE int LSS_NAME(statfs64)(const char *p,
2828 struct kernel_statfs64 *b) {
2829 return LSS_NAME(_statfs64)(p, sizeof(*b), b);
2830 }
2831 LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) {
2832 return LSS_NAME(_fstatfs64)(f, sizeof(*b), b);
2833 }
2834 #endif
2835
2836 LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) {
2837 extern char **environ;
2838 return LSS_NAME(execve)(path, argv, (const char *const *)environ);
2839 }
2840
2841 LSS_INLINE pid_t LSS_NAME(gettid)() {
2842 pid_t tid = LSS_NAME(_gettid)();
2843 if (tid != -1) {
2844 return tid;
2845 }
2846 return LSS_NAME(getpid)();
2847 }
2848
2849 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
2850 size_t new_size, int flags, ...) {
2851 va_list ap;
2852 void *new_address, *rc;
2853 va_start(ap, flags);
2854 new_address = va_arg(ap, void *);
2855 rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
2856 flags, new_address);
2857 va_end(ap);
2858 return rc;
2859 }
2860
2861 LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) {
2862 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
2863 * then sends job control signals to the real parent, rather than to
2864 * the tracer. We reduce the risk of this happening by starting a
2865 * whole new time slice, and then quickly sending a SIGCONT signal
2866 * right after detaching from the tracee.
2867 */
2868 int rc, err;
2869 LSS_NAME(sched_yield)();
2870 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
2871 err = LSS_ERRNO;
2872 LSS_NAME(kill)(pid, SIGCONT);
2873 LSS_ERRNO = err;
2874 return rc;
2875 }
2876
2877 LSS_INLINE int LSS_NAME(raise)(int sig) {
2878 return LSS_NAME(kill)(LSS_NAME(getpid)(), sig);
2879 }
2880
2881 LSS_INLINE int LSS_NAME(setpgrp)() {
2882 return LSS_NAME(setpgid)(0, 0);
2883 }
2884
2885 LSS_INLINE int LSS_NAME(sysconf)(int name) {
2886 extern int __getpagesize(void);
2887 switch (name) {
2888 case _SC_OPEN_MAX: {
2889 struct kernel_rlimit limit;
2890 #if defined(__ARM_EABI__)
2891 return LSS_NAME(ugetrlimit)(RLIMIT_NOFILE, &limit) < 0
2892 ? 8192 : limit.rlim_cur;
2893 #else
2894 return LSS_NAME(getrlimit)(RLIMIT_NOFILE, &limit) < 0
2895 ? 8192 : limit.rlim_cur;
2896 #endif
2897 }
2898 case _SC_PAGESIZE:
2899 return __getpagesize();
2900 default:
2901 errno = ENOSYS;
2902 return -1;
2903 }
2904 }
2905 #if defined(__x86_64__) || \
2906 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64)
2907 /* pread64() and pwrite64() do not exist on 64-bit systems... */
2908 LSS_INLINE _syscall3(int, readahead, int, f,
2909 loff_t, o, unsigned, c)
2910 #else
2911 #define __NR__pread64 __NR_pread64
2912 #define __NR__pwrite64 __NR_pwrite64
2913 #define __NR__readahead __NR_readahead
2914 LSS_INLINE _syscall5(ssize_t, _pread64, int, f,
2915 void *, b, size_t, c, unsigned, o1,
2916 unsigned, o2)
2917 LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f,
2918 const void *, b, size_t, c, unsigned, o1,
2919 long, o2)
2920 LSS_INLINE _syscall4(int, _readahead, int, f,
2921 unsigned, o1, unsigned, o2, size_t, c)
2922 /* We force 64bit-wide parameters onto the stack, then access each
2923 * 32-bit component individually. This guarantees that we build the
2924 * correct parameters independent of the native byte-order of the
2925 * underlying architecture.
2926 */
2927 LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count,
2928 loff_t off) {
2929 union { loff_t off; unsigned arg[2]; } o = { off };
2930 return LSS_NAME(_pread64)(fd, buf, count, o.arg[0], o.arg[1]);
2931 }
2932 LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf,
2933 size_t count, loff_t off) {
2934 union { loff_t off; unsigned arg[2]; } o = { off };
2935 return LSS_NAME(_pwrite64)(fd, buf, count, o.arg[0], o.arg[1]);
2936 }
2937 LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, int len) {
2938 union { loff_t off; unsigned arg[2]; } o = { off };
2939 return LSS_NAME(_readahead)(fd, o.arg[0], o.arg[1], len);
2940 }
2941 #endif
2942 #endif
2943
2944 #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
2945 }
2946 #endif
2947
2948 #endif
2949 #endif
OLDNEW
« no previous file with comments | « obsolete/breakpad/common/linux/linux_libc_support_unittest.cc ('k') | obsolete/breakpad/common/linux/memory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698