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

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

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

Powered by Google App Engine
This is Rietveld 408576698