blob: 56b8facd6d5a65720ebff1f24e06f10b018bd771 [file] [log] [blame]
Austin Schuh745610d2015-09-06 18:19:50 -07001// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
2/* Copyright (c) 2005-2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * ---
32 * Author: Markus Gutschke
33 */
34
35/* This file includes Linux-specific support functions common to the
36 * coredumper and the thread lister; primarily, this is a collection
37 * of direct system calls, and a couple of symbols missing from
38 * standard header files.
39 * There are a few options that the including file can set to control
40 * the behavior of this file:
41 *
42 * SYS_CPLUSPLUS:
43 * The entire header file will normally be wrapped in 'extern "C" { }",
44 * making it suitable for compilation as both C and C++ source. If you
45 * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit
46 * the wrapping. N.B. doing so will suppress inclusion of all prerequisite
47 * system header files, too. It is the caller's responsibility to provide
48 * the necessary definitions.
49 *
50 * SYS_ERRNO:
51 * All system calls will update "errno" unless overriden by setting the
52 * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be
53 * an l-value.
54 *
55 * SYS_INLINE:
56 * New symbols will be defined "static inline", unless overridden by
57 * the SYS_INLINE macro.
58 *
59 * SYS_LINUX_SYSCALL_SUPPORT_H
60 * This macro is used to avoid multiple inclusions of this header file.
61 * If you need to include this file more than once, make sure to
62 * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion.
63 *
64 * SYS_PREFIX:
65 * New system calls will have a prefix of "sys_" unless overridden by
66 * the SYS_PREFIX macro. Valid values for this macro are [0..9] which
67 * results in prefixes "sys[0..9]_". It is also possible to set this
68 * macro to -1, which avoids all prefixes.
69 *
70 * This file defines a few internal symbols that all start with "LSS_".
71 * Do not access these symbols from outside this file. They are not part
72 * of the supported API.
73 *
74 * NOTE: This is a stripped down version of the official opensource
75 * version of linux_syscall_support.h, which lives at
76 * http://code.google.com/p/linux-syscall-support/
77 * It includes only the syscalls that are used in perftools, plus a
78 * few extra. Here's the breakdown:
79 * 1) Perftools uses these: grep -rho 'sys_[a-z0-9_A-Z]* *(' src | sort -u
80 * sys__exit(
81 * sys_clone(
82 * sys_close(
83 * sys_fcntl(
84 * sys_fstat(
85 * sys_futex(
86 * sys_getcpu(
87 * sys_getdents64(
88 * sys_getppid(
89 * sys_gettid(
90 * sys_lseek(
91 * sys_mmap(
92 * sys_mremap(
93 * sys_munmap(
94 * sys_open(
95 * sys_pipe(
96 * sys_prctl(
97 * sys_ptrace(
98 * sys_ptrace_detach(
99 * sys_read(
100 * sys_sched_yield(
101 * sys_sigaction(
102 * sys_sigaltstack(
103 * sys_sigdelset(
104 * sys_sigfillset(
105 * sys_sigprocmask(
106 * sys_socket(
107 * sys_stat(
108 * sys_waitpid(
109 * 2) These are used as subroutines of the above:
110 * sys_getpid -- gettid
111 * sys_kill -- ptrace_detach
112 * sys_restore -- sigaction
113 * sys_restore_rt -- sigaction
114 * sys_socketcall -- socket
115 * sys_wait4 -- waitpid
116 * 3) I left these in even though they're not used. They either
117 * complement the above (write vs read) or are variants (rt_sigaction):
118 * sys_fstat64
119 * sys_llseek
120 * sys_mmap2
121 * sys_openat
122 * sys_getdents
123 * sys_rt_sigaction
124 * sys_rt_sigprocmask
125 * sys_sigaddset
126 * sys_sigemptyset
127 * sys_stat64
128 * sys_write
129 */
130#ifndef SYS_LINUX_SYSCALL_SUPPORT_H
131#define SYS_LINUX_SYSCALL_SUPPORT_H
132
133/* We currently only support x86-32, x86-64, ARM, MIPS, PPC/PPC64 and Aarch64 on Linux.
134 * Porting to other related platforms should not be difficult.
135 */
136#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
137 defined(__mips__) || defined(__PPC__) || defined(__aarch64__)) && defined(__linux)
138
139#ifndef SYS_CPLUSPLUS
140#ifdef __cplusplus
141/* Some system header files in older versions of gcc neglect to properly
142 * handle being included from C++. As it appears to be harmless to have
143 * multiple nested 'extern "C"' blocks, just add another one here.
144 */
145extern "C" {
146#endif
147
148#include <errno.h>
149#include <signal.h>
150#include <stdarg.h>
151#include <stddef.h>
152#include <stdint.h>
153#include <string.h>
154#include <sys/ptrace.h>
155#include <sys/resource.h>
156#include <sys/time.h>
157#include <sys/types.h>
158#include <syscall.h>
159#include <unistd.h>
160#include <linux/unistd.h>
161#include <endian.h>
162
163#ifdef __mips__
164/* Include definitions of the ABI currently in use. */
165#include <sgidefs.h>
166#endif
167
168#endif
169
170/* As glibc often provides subtly incompatible data structures (and implicit
171 * wrapper functions that convert them), we provide our own kernel data
172 * structures for use by the system calls.
173 * These structures have been developed by using Linux 2.6.23 headers for
174 * reference. Note though, we do not care about exact API compatibility
175 * with the kernel, and in fact the kernel often does not have a single
176 * API that works across architectures. Instead, we try to mimic the glibc
177 * API where reasonable, and only guarantee ABI compatibility with the
178 * kernel headers.
179 * Most notably, here are a few changes that were made to the structures
180 * defined by kernel headers:
181 *
182 * - we only define structures, but not symbolic names for kernel data
183 * types. For the latter, we directly use the native C datatype
184 * (i.e. "unsigned" instead of "mode_t").
185 * - in a few cases, it is possible to define identical structures for
186 * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by
187 * standardizing on the 64bit version of the data types. In particular,
188 * this means that we use "unsigned" where the 32bit headers say
189 * "unsigned long".
190 * - overall, we try to minimize the number of cases where we need to
191 * conditionally define different structures.
192 * - the "struct kernel_sigaction" class of structures have been
193 * modified to more closely mimic glibc's API by introducing an
194 * anonymous union for the function pointer.
195 * - a small number of field names had to have an underscore appended to
196 * them, because glibc defines a global macro by the same name.
197 */
198
199/* include/linux/dirent.h */
200struct kernel_dirent64 {
201 unsigned long long d_ino;
202 long long d_off;
203 unsigned short d_reclen;
204 unsigned char d_type;
205 char d_name[256];
206};
207
208/* include/linux/dirent.h */
209struct kernel_dirent {
210 long d_ino;
211 long d_off;
212 unsigned short d_reclen;
213 char d_name[256];
214};
215
216/* include/linux/time.h */
217struct kernel_timespec {
218 long tv_sec;
219 long tv_nsec;
220};
221
222/* include/linux/time.h */
223struct kernel_timeval {
224 long tv_sec;
225 long tv_usec;
226};
227
228/* include/linux/resource.h */
229struct kernel_rusage {
230 struct kernel_timeval ru_utime;
231 struct kernel_timeval ru_stime;
232 long ru_maxrss;
233 long ru_ixrss;
234 long ru_idrss;
235 long ru_isrss;
236 long ru_minflt;
237 long ru_majflt;
238 long ru_nswap;
239 long ru_inblock;
240 long ru_oublock;
241 long ru_msgsnd;
242 long ru_msgrcv;
243 long ru_nsignals;
244 long ru_nvcsw;
245 long ru_nivcsw;
246};
247
248#if defined(__i386__) || defined(__arm__) || defined(__PPC__)
249
250/* include/asm-{arm,i386,mips,ppc}/signal.h */
251struct kernel_old_sigaction {
252 union {
253 void (*sa_handler_)(int);
254 void (*sa_sigaction_)(int, siginfo_t *, void *);
255 };
256 unsigned long sa_mask;
257 unsigned long sa_flags;
258 void (*sa_restorer)(void);
259} __attribute__((packed,aligned(4)));
260#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
261 #define kernel_old_sigaction kernel_sigaction
262#endif
263
264/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the
265 * exactly match the size of the signal set, even though the API was
266 * intended to be extensible. We define our own KERNEL_NSIG to deal with
267 * this.
268 * Please note that glibc provides signals [1.._NSIG-1], whereas the
269 * kernel (and this header) provides the range [1..KERNEL_NSIG]. The
270 * actual number of signals is obviously the same, but the constants
271 * differ by one.
272 */
273#ifdef __mips__
274#define KERNEL_NSIG 128
275#else
276#define KERNEL_NSIG 64
277#endif
278
279/* include/asm-{arm,i386,mips,x86_64}/signal.h */
280struct kernel_sigset_t {
281 unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/
282 (8*sizeof(unsigned long))];
283};
284
285/* include/asm-{arm,generic,i386,mips,x86_64,ppc}/signal.h */
286struct kernel_sigaction {
287#ifdef __mips__
288 unsigned long sa_flags;
289 union {
290 void (*sa_handler_)(int);
291 void (*sa_sigaction_)(int, siginfo_t *, void *);
292 };
293 struct kernel_sigset_t sa_mask;
294#else
295 union {
296 void (*sa_handler_)(int);
297 void (*sa_sigaction_)(int, siginfo_t *, void *);
298 };
299 unsigned long sa_flags;
300 void (*sa_restorer)(void);
301 struct kernel_sigset_t sa_mask;
302#endif
303};
304
305/* include/asm-{arm,i386,mips,ppc}/stat.h */
306#ifdef __mips__
307#if _MIPS_SIM == _MIPS_SIM_ABI64
308struct kernel_stat {
309#else
310struct kernel_stat64 {
311#endif
312 unsigned st_dev;
313 unsigned __pad0[3];
314 unsigned long long st_ino;
315 unsigned st_mode;
316 unsigned st_nlink;
317 unsigned st_uid;
318 unsigned st_gid;
319 unsigned st_rdev;
320 unsigned __pad1[3];
321 long long st_size;
322 unsigned st_atime_;
323 unsigned st_atime_nsec_;
324 unsigned st_mtime_;
325 unsigned st_mtime_nsec_;
326 unsigned st_ctime_;
327 unsigned st_ctime_nsec_;
328 unsigned st_blksize;
329 unsigned __pad2;
330 unsigned long long st_blocks;
331};
332#elif defined __PPC__
333struct kernel_stat64 {
334 unsigned long long st_dev;
335 unsigned long long st_ino;
336 unsigned st_nlink;
337 unsigned st_mode;
338 unsigned st_uid;
339 unsigned st_gid;
340 int __pad2;
341 unsigned long long st_rdev;
342 long long st_size;
343 long long st_blksize;
344 long long st_blocks;
345 kernel_timespec st_atim;
346 kernel_timespec st_mtim;
347 kernel_timespec st_ctim;
348 unsigned long __unused4;
349 unsigned long __unused5;
350 unsigned long __unused6;
351};
352#else
353struct kernel_stat64 {
354 unsigned long long st_dev;
355 unsigned char __pad0[4];
356 unsigned __st_ino;
357 unsigned st_mode;
358 unsigned st_nlink;
359 unsigned st_uid;
360 unsigned st_gid;
361 unsigned long long st_rdev;
362 unsigned char __pad3[4];
363 long long st_size;
364 unsigned st_blksize;
365 unsigned long long st_blocks;
366 unsigned st_atime_;
367 unsigned st_atime_nsec_;
368 unsigned st_mtime_;
369 unsigned st_mtime_nsec_;
370 unsigned st_ctime_;
371 unsigned st_ctime_nsec_;
372 unsigned long long st_ino;
373};
374#endif
375
376/* include/asm-{arm,generic,i386,mips,x86_64,ppc}/stat.h */
377#if defined(__i386__) || defined(__arm__)
378struct kernel_stat {
379 /* The kernel headers suggest that st_dev and st_rdev should be 32bit
380 * quantities encoding 12bit major and 20bit minor numbers in an interleaved
381 * format. In reality, we do not see useful data in the top bits. So,
382 * we'll leave the padding in here, until we find a better solution.
383 */
384 unsigned short st_dev;
385 short pad1;
386 unsigned st_ino;
387 unsigned short st_mode;
388 unsigned short st_nlink;
389 unsigned short st_uid;
390 unsigned short st_gid;
391 unsigned short st_rdev;
392 short pad2;
393 unsigned st_size;
394 unsigned st_blksize;
395 unsigned st_blocks;
396 unsigned st_atime_;
397 unsigned st_atime_nsec_;
398 unsigned st_mtime_;
399 unsigned st_mtime_nsec_;
400 unsigned st_ctime_;
401 unsigned st_ctime_nsec_;
402 unsigned __unused4;
403 unsigned __unused5;
404};
405#elif defined(__x86_64__)
406struct kernel_stat {
407 uint64_t st_dev;
408 uint64_t st_ino;
409 uint64_t st_nlink;
410 unsigned st_mode;
411 unsigned st_uid;
412 unsigned st_gid;
413 unsigned __pad0;
414 uint64_t st_rdev;
415 int64_t st_size;
416 int64_t st_blksize;
417 int64_t st_blocks;
418 uint64_t st_atime_;
419 uint64_t st_atime_nsec_;
420 uint64_t st_mtime_;
421 uint64_t st_mtime_nsec_;
422 uint64_t st_ctime_;
423 uint64_t st_ctime_nsec_;
424 int64_t __unused[3];
425};
426#elif defined(__PPC__)
427struct kernel_stat {
428 unsigned long long st_dev;
429 unsigned long st_ino;
430 unsigned long st_nlink;
431 unsigned long st_mode;
432 unsigned st_uid;
433 unsigned st_gid;
434 int __pad2;
435 unsigned long long st_rdev;
436 long st_size;
437 unsigned long st_blksize;
438 unsigned long st_blocks;
439 kernel_timespec st_atim;
440 kernel_timespec st_mtim;
441 kernel_timespec st_ctim;
442 unsigned long __unused4;
443 unsigned long __unused5;
444 unsigned long __unused6;
445};
446#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)
447struct kernel_stat {
448 unsigned st_dev;
449 int st_pad1[3];
450 unsigned st_ino;
451 unsigned st_mode;
452 unsigned st_nlink;
453 unsigned st_uid;
454 unsigned st_gid;
455 unsigned st_rdev;
456 int st_pad2[2];
457 long st_size;
458 int st_pad3;
459 long st_atime_;
460 long st_atime_nsec_;
461 long st_mtime_;
462 long st_mtime_nsec_;
463 long st_ctime_;
464 long st_ctime_nsec_;
465 int st_blksize;
466 int st_blocks;
467 int st_pad4[14];
468};
469#elif defined(__aarch64__)
470struct kernel_stat {
471 unsigned long st_dev;
472 unsigned long st_ino;
473 unsigned int st_mode;
474 unsigned int st_nlink;
475 unsigned int st_uid;
476 unsigned int st_gid;
477 unsigned long st_rdev;
478 unsigned long __pad1;
479 long st_size;
480 int st_blksize;
481 int __pad2;
482 long st_blocks;
483 long st_atime_;
484 unsigned long st_atime_nsec_;
485 long st_mtime_;
486 unsigned long st_mtime_nsec_;
487 long st_ctime_;
488 unsigned long st_ctime_nsec_;
489 unsigned int __unused4;
490 unsigned int __unused5;
491};
492#endif
493
494
495/* Definitions missing from the standard header files */
496#ifndef O_DIRECTORY
497#if defined(__arm__)
498#define O_DIRECTORY 0040000
499#else
500#define O_DIRECTORY 0200000
501#endif
502#endif
503#ifndef PR_GET_DUMPABLE
504#define PR_GET_DUMPABLE 3
505#endif
506#ifndef PR_SET_DUMPABLE
507#define PR_SET_DUMPABLE 4
508#endif
509#ifndef AT_FDCWD
510#define AT_FDCWD (-100)
511#endif
512#ifndef AT_SYMLINK_NOFOLLOW
513#define AT_SYMLINK_NOFOLLOW 0x100
514#endif
515#ifndef AT_REMOVEDIR
516#define AT_REMOVEDIR 0x200
517#endif
518#ifndef MREMAP_FIXED
519#define MREMAP_FIXED 2
520#endif
521#ifndef SA_RESTORER
522#define SA_RESTORER 0x04000000
523#endif
524
525#if defined(__i386__)
526#ifndef __NR_rt_sigaction
527#define __NR_rt_sigaction 174
528#define __NR_rt_sigprocmask 175
529#endif
530#ifndef __NR_stat64
531#define __NR_stat64 195
532#endif
533#ifndef __NR_fstat64
534#define __NR_fstat64 197
535#endif
536#ifndef __NR_getdents64
537#define __NR_getdents64 220
538#endif
539#ifndef __NR_gettid
540#define __NR_gettid 224
541#endif
542#ifndef __NR_futex
543#define __NR_futex 240
544#endif
545#ifndef __NR_openat
546#define __NR_openat 295
547#endif
548#ifndef __NR_getcpu
549#define __NR_getcpu 318
550#endif
551/* End of i386 definitions */
552#elif defined(__arm__)
553#ifndef __syscall
554#if defined(__thumb__) || defined(__ARM_EABI__)
555#define __SYS_REG(name) register long __sysreg __asm__("r6") = __NR_##name;
556#define __SYS_REG_LIST(regs...) [sysreg] "r" (__sysreg) , ##regs
557#define __syscall(name) "swi\t0"
558#define __syscall_safe(name) \
559 "push {r7}\n" \
560 "mov r7,%[sysreg]\n" \
561 __syscall(name)"\n" \
562 "pop {r7}"
563#else
564#define __SYS_REG(name)
565#define __SYS_REG_LIST(regs...) regs
566#define __syscall(name) "swi\t" __sys1(__NR_##name) ""
567#define __syscall_safe(name) __syscall(name)
568#endif
569#endif
570#ifndef __NR_rt_sigaction
571#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
572#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
573#endif
574#ifndef __NR_stat64
575#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
576#endif
577#ifndef __NR_fstat64
578#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
579#endif
580#ifndef __NR_getdents64
581#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
582#endif
583#ifndef __NR_gettid
584#define __NR_gettid (__NR_SYSCALL_BASE + 224)
585#endif
586#ifndef __NR_futex
587#define __NR_futex (__NR_SYSCALL_BASE + 240)
588#endif
589/* End of ARM definitions */
590#elif defined(__x86_64__)
591#ifndef __NR_gettid
592#define __NR_gettid 186
593#endif
594#ifndef __NR_futex
595#define __NR_futex 202
596#endif
597#ifndef __NR_getdents64
598#define __NR_getdents64 217
599#endif
600#ifndef __NR_openat
601#define __NR_openat 257
602#endif
603/* End of x86-64 definitions */
604#elif defined(__mips__)
605#if _MIPS_SIM == _MIPS_SIM_ABI32
606#ifndef __NR_rt_sigaction
607#define __NR_rt_sigaction (__NR_Linux + 194)
608#define __NR_rt_sigprocmask (__NR_Linux + 195)
609#endif
610#ifndef __NR_stat64
611#define __NR_stat64 (__NR_Linux + 213)
612#endif
613#ifndef __NR_fstat64
614#define __NR_fstat64 (__NR_Linux + 215)
615#endif
616#ifndef __NR_getdents64
617#define __NR_getdents64 (__NR_Linux + 219)
618#endif
619#ifndef __NR_gettid
620#define __NR_gettid (__NR_Linux + 222)
621#endif
622#ifndef __NR_futex
623#define __NR_futex (__NR_Linux + 238)
624#endif
625#ifndef __NR_openat
626#define __NR_openat (__NR_Linux + 288)
627#endif
628#ifndef __NR_fstatat
629#define __NR_fstatat (__NR_Linux + 293)
630#endif
631#ifndef __NR_getcpu
632#define __NR_getcpu (__NR_Linux + 312)
633#endif
634/* End of MIPS (old 32bit API) definitions */
635#elif _MIPS_SIM == _MIPS_SIM_ABI64
636#ifndef __NR_gettid
637#define __NR_gettid (__NR_Linux + 178)
638#endif
639#ifndef __NR_futex
640#define __NR_futex (__NR_Linux + 194)
641#endif
642#ifndef __NR_openat
643#define __NR_openat (__NR_Linux + 247)
644#endif
645#ifndef __NR_fstatat
646#define __NR_fstatat (__NR_Linux + 252)
647#endif
648#ifndef __NR_getcpu
649#define __NR_getcpu (__NR_Linux + 271)
650#endif
651/* End of MIPS (64bit API) definitions */
652#else
653#ifndef __NR_gettid
654#define __NR_gettid (__NR_Linux + 178)
655#endif
656#ifndef __NR_futex
657#define __NR_futex (__NR_Linux + 194)
658#endif
659#ifndef __NR_openat
660#define __NR_openat (__NR_Linux + 251)
661#endif
662#ifndef __NR_fstatat
663#define __NR_fstatat (__NR_Linux + 256)
664#endif
665#ifndef __NR_getcpu
666#define __NR_getcpu (__NR_Linux + 275)
667#endif
668/* End of MIPS (new 32bit API) definitions */
669#endif
670/* End of MIPS definitions */
671#elif defined(__PPC__)
672#ifndef __NR_rt_sigaction
673#define __NR_rt_sigaction 173
674#define __NR_rt_sigprocmask 174
675#endif
676#ifndef __NR_stat64
677#define __NR_stat64 195
678#endif
679#ifndef __NR_fstat64
680#define __NR_fstat64 197
681#endif
682#ifndef __NR_socket
683#define __NR_socket 198
684#endif
685#ifndef __NR_getdents64
686#define __NR_getdents64 202
687#endif
688#ifndef __NR_gettid
689#define __NR_gettid 207
690#endif
691#ifndef __NR_futex
692#define __NR_futex 221
693#endif
694#ifndef __NR_openat
695#define __NR_openat 286
696#endif
697#ifndef __NR_getcpu
698#define __NR_getcpu 302
699#endif
700/* End of powerpc defininitions */
701#elif defined(__aarch64__)
702#ifndef __NR_fstatat
703#define __NR_fstatat 79
704#endif
705/* End of aarch64 defininitions */
706#endif
707
708
709/* After forking, we must make sure to only call system calls. */
710#if __BOUNDED_POINTERS__
711 #error "Need to port invocations of syscalls for bounded ptrs"
712#else
713 /* The core dumper and the thread lister get executed after threads
714 * have been suspended. As a consequence, we cannot call any functions
715 * that acquire locks. Unfortunately, libc wraps most system calls
716 * (e.g. in order to implement pthread_atfork, and to make calls
717 * cancellable), which means we cannot call these functions. Instead,
718 * we have to call syscall() directly.
719 */
720 #undef LSS_ERRNO
721 #ifdef SYS_ERRNO
722 /* Allow the including file to override the location of errno. This can
723 * be useful when using clone() with the CLONE_VM option.
724 */
725 #define LSS_ERRNO SYS_ERRNO
726 #else
727 #define LSS_ERRNO errno
728 #endif
729
730 #undef LSS_INLINE
731 #ifdef SYS_INLINE
732 #define LSS_INLINE SYS_INLINE
733 #else
734 #define LSS_INLINE static inline
735 #endif
736
737 /* Allow the including file to override the prefix used for all new
738 * system calls. By default, it will be set to "sys_".
739 */
740 #undef LSS_NAME
741 #ifndef SYS_PREFIX
742 #define LSS_NAME(name) sys_##name
743 #elif SYS_PREFIX < 0
744 #define LSS_NAME(name) name
745 #elif SYS_PREFIX == 0
746 #define LSS_NAME(name) sys0_##name
747 #elif SYS_PREFIX == 1
748 #define LSS_NAME(name) sys1_##name
749 #elif SYS_PREFIX == 2
750 #define LSS_NAME(name) sys2_##name
751 #elif SYS_PREFIX == 3
752 #define LSS_NAME(name) sys3_##name
753 #elif SYS_PREFIX == 4
754 #define LSS_NAME(name) sys4_##name
755 #elif SYS_PREFIX == 5
756 #define LSS_NAME(name) sys5_##name
757 #elif SYS_PREFIX == 6
758 #define LSS_NAME(name) sys6_##name
759 #elif SYS_PREFIX == 7
760 #define LSS_NAME(name) sys7_##name
761 #elif SYS_PREFIX == 8
762 #define LSS_NAME(name) sys8_##name
763 #elif SYS_PREFIX == 9
764 #define LSS_NAME(name) sys9_##name
765 #endif
766
767 #undef LSS_RETURN
768 #if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
769 defined(__aarch64__))
770 /* Failing system calls return a negative result in the range of
771 * -1..-4095. These are "errno" values with the sign inverted.
772 */
773 #define LSS_RETURN(type, res) \
774 do { \
775 if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
776 LSS_ERRNO = -(res); \
777 res = -1; \
778 } \
779 return (type) (res); \
780 } while (0)
781 #elif defined(__mips__)
782 /* On MIPS, failing system calls return -1, and set errno in a
783 * separate CPU register.
784 */
785 #define LSS_RETURN(type, res, err) \
786 do { \
787 if (err) { \
788 LSS_ERRNO = (res); \
789 res = -1; \
790 } \
791 return (type) (res); \
792 } while (0)
793 #elif defined(__PPC__)
794 /* On PPC, failing system calls return -1, and set errno in a
795 * separate CPU register. See linux/unistd.h.
796 */
797 #define LSS_RETURN(type, res, err) \
798 do { \
799 if (err & 0x10000000 ) { \
800 LSS_ERRNO = (res); \
801 res = -1; \
802 } \
803 return (type) (res); \
804 } while (0)
805 #endif
806 #if defined(__i386__)
807 #if defined(NO_FRAME_POINTER) && (100 * __GNUC__ + __GNUC_MINOR__ >= 404)
808 /* This only works for GCC-4.4 and above -- the first version to use
809 .cfi directives for dwarf unwind info. */
810 #define CFI_ADJUST_CFA_OFFSET(adjust) \
811 ".cfi_adjust_cfa_offset " #adjust "\n"
812 #else
813 #define CFI_ADJUST_CFA_OFFSET(adjust) /**/
814 #endif
815
816 /* In PIC mode (e.g. when building shared libraries), gcc for i386
817 * reserves ebx. Unfortunately, most distribution ship with implementations
818 * of _syscallX() which clobber ebx.
819 * Also, most definitions of _syscallX() neglect to mark "memory" as being
820 * clobbered. This causes problems with compilers, that do a better job
821 * at optimizing across __asm__ calls.
822 * So, we just have to redefine all of the _syscallX() macros.
823 */
824 #undef LSS_BODY
825 #define LSS_BODY(type,args...) \
826 long __res; \
827 __asm__ __volatile__("push %%ebx\n" \
828 CFI_ADJUST_CFA_OFFSET(4) \
829 "movl %2,%%ebx\n" \
830 "int $0x80\n" \
831 "pop %%ebx\n" \
832 CFI_ADJUST_CFA_OFFSET(-4) \
833 args \
834 : "esp", "memory"); \
835 LSS_RETURN(type,__res)
836 #undef _syscall0
837 #define _syscall0(type,name) \
838 type LSS_NAME(name)(void) { \
839 long __res; \
840 __asm__ volatile("int $0x80" \
841 : "=a" (__res) \
842 : "0" (__NR_##name) \
843 : "memory"); \
844 LSS_RETURN(type,__res); \
845 }
846 #undef _syscall1
847 #define _syscall1(type,name,type1,arg1) \
848 type LSS_NAME(name)(type1 arg1) { \
849 LSS_BODY(type, \
850 : "=a" (__res) \
851 : "0" (__NR_##name), "ri" ((long)(arg1))); \
852 }
853 #undef _syscall2
854 #define _syscall2(type,name,type1,arg1,type2,arg2) \
855 type LSS_NAME(name)(type1 arg1,type2 arg2) { \
856 LSS_BODY(type, \
857 : "=a" (__res) \
858 : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
859 }
860 #undef _syscall3
861 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
862 type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
863 LSS_BODY(type, \
864 : "=a" (__res) \
865 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
866 "d" ((long)(arg3))); \
867 }
868 #undef _syscall4
869 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
870 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
871 LSS_BODY(type, \
872 : "=a" (__res) \
873 : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
874 "d" ((long)(arg3)),"S" ((long)(arg4))); \
875 }
876 #undef _syscall5
877 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
878 type5,arg5) \
879 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
880 type5 arg5) { \
881 long __res; \
882 __asm__ __volatile__("push %%ebx\n" \
883 "movl %2,%%ebx\n" \
884 "movl %1,%%eax\n" \
885 "int $0x80\n" \
886 "pop %%ebx" \
887 : "=a" (__res) \
888 : "i" (__NR_##name), "ri" ((long)(arg1)), \
889 "c" ((long)(arg2)), "d" ((long)(arg3)), \
890 "S" ((long)(arg4)), "D" ((long)(arg5)) \
891 : "esp", "memory"); \
892 LSS_RETURN(type,__res); \
893 }
894 #undef _syscall6
895 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
896 type5,arg5,type6,arg6) \
897 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
898 type5 arg5, type6 arg6) { \
899 long __res; \
900 struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
901 __asm__ __volatile__("push %%ebp\n" \
902 "push %%ebx\n" \
903 "movl 4(%2),%%ebp\n" \
904 "movl 0(%2), %%ebx\n" \
905 "movl %1,%%eax\n" \
906 "int $0x80\n" \
907 "pop %%ebx\n" \
908 "pop %%ebp" \
909 : "=a" (__res) \
910 : "i" (__NR_##name), "0" ((long)(&__s)), \
911 "c" ((long)(arg2)), "d" ((long)(arg3)), \
912 "S" ((long)(arg4)), "D" ((long)(arg5)) \
913 : "esp", "memory"); \
914 LSS_RETURN(type,__res); \
915 }
916 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
917 int flags, void *arg, int *parent_tidptr,
918 void *newtls, int *child_tidptr) {
919 long __res;
920 __asm__ __volatile__(/* if (fn == NULL)
921 * return -EINVAL;
922 */
923 "movl %3,%%ecx\n"
924 "jecxz 1f\n"
925
926 /* if (child_stack == NULL)
927 * return -EINVAL;
928 */
929 "movl %4,%%ecx\n"
930 "jecxz 1f\n"
931
932 /* Set up alignment of the child stack:
933 * child_stack = (child_stack & ~0xF) - 20;
934 */
935 "andl $-16,%%ecx\n"
936 "subl $20,%%ecx\n"
937
938 /* Push "arg" and "fn" onto the stack that will be
939 * used by the child.
940 */
941 "movl %6,%%eax\n"
942 "movl %%eax,4(%%ecx)\n"
943 "movl %3,%%eax\n"
944 "movl %%eax,(%%ecx)\n"
945
946 /* %eax = syscall(%eax = __NR_clone,
947 * %ebx = flags,
948 * %ecx = child_stack,
949 * %edx = parent_tidptr,
950 * %esi = newtls,
951 * %edi = child_tidptr)
952 * Also, make sure that %ebx gets preserved as it is
953 * used in PIC mode.
954 */
955 "movl %8,%%esi\n"
956 "movl %7,%%edx\n"
957 "movl %5,%%eax\n"
958 "movl %9,%%edi\n"
959 "pushl %%ebx\n"
960 "movl %%eax,%%ebx\n"
961 "movl %2,%%eax\n"
962 "int $0x80\n"
963
964 /* In the parent: restore %ebx
965 * In the child: move "fn" into %ebx
966 */
967 "popl %%ebx\n"
968
969 /* if (%eax != 0)
970 * return %eax;
971 */
972 "test %%eax,%%eax\n"
973 "jnz 1f\n"
974
975 /* In the child, now. Terminate frame pointer chain.
976 */
977 "movl $0,%%ebp\n"
978
979 /* Call "fn". "arg" is already on the stack.
980 */
981 "call *%%ebx\n"
982
983 /* Call _exit(%ebx). Unfortunately older versions
984 * of gcc restrict the number of arguments that can
985 * be passed to asm(). So, we need to hard-code the
986 * system call number.
987 */
988 "movl %%eax,%%ebx\n"
989 "movl $1,%%eax\n"
990 "int $0x80\n"
991
992 /* Return to parent.
993 */
994 "1:\n"
995 : "=a" (__res)
996 : "0"(-EINVAL), "i"(__NR_clone),
997 "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
998 "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
999 : "esp", "memory", "ecx", "edx", "esi", "edi");
1000 LSS_RETURN(int, __res);
1001 }
1002
1003 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
1004 /* On i386, the kernel does not know how to return from a signal
1005 * handler. Instead, it relies on user space to provide a
1006 * restorer function that calls the {rt_,}sigreturn() system call.
1007 * Unfortunately, we cannot just reference the glibc version of this
1008 * function, as glibc goes out of its way to make it inaccessible.
1009 */
1010 void (*res)(void);
1011 __asm__ __volatile__("call 2f\n"
1012 "0:.align 16\n"
1013 "1:movl %1,%%eax\n"
1014 "int $0x80\n"
1015 "2:popl %0\n"
1016 "addl $(1b-0b),%0\n"
1017 : "=a" (res)
1018 : "i" (__NR_rt_sigreturn));
1019 return res;
1020 }
1021 LSS_INLINE void (*LSS_NAME(restore)(void))(void) {
1022 /* On i386, the kernel does not know how to return from a signal
1023 * handler. Instead, it relies on user space to provide a
1024 * restorer function that calls the {rt_,}sigreturn() system call.
1025 * Unfortunately, we cannot just reference the glibc version of this
1026 * function, as glibc goes out of its way to make it inaccessible.
1027 */
1028 void (*res)(void);
1029 __asm__ __volatile__("call 2f\n"
1030 "0:.align 16\n"
1031 "1:pop %%eax\n"
1032 "movl %1,%%eax\n"
1033 "int $0x80\n"
1034 "2:popl %0\n"
1035 "addl $(1b-0b),%0\n"
1036 : "=a" (res)
1037 : "i" (__NR_sigreturn));
1038 return res;
1039 }
1040 #elif defined(__x86_64__)
1041 /* There are no known problems with any of the _syscallX() macros
1042 * currently shipping for x86_64, but we still need to be able to define
1043 * our own version so that we can override the location of the errno
1044 * location (e.g. when using the clone() system call with the CLONE_VM
1045 * option).
1046 */
1047 #undef LSS_ENTRYPOINT
1048 #define LSS_ENTRYPOINT "syscall\n"
1049
1050 /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
1051 * We need to explicitly cast to an unsigned 64 bit type to avoid implicit
1052 * sign extension. We can't cast pointers directly because those are
1053 * 32 bits, and gcc will dump ugly warnings about casting from a pointer
1054 * to an integer of a different size.
1055 */
1056 #undef LSS_SYSCALL_ARG
1057 #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a))
1058 #undef _LSS_RETURN
1059 #define _LSS_RETURN(type, res, cast) \
1060 do { \
1061 if ((uint64_t)(res) >= (uint64_t)(-4095)) { \
1062 LSS_ERRNO = -(res); \
1063 res = -1; \
1064 } \
1065 return (type)(cast)(res); \
1066 } while (0)
1067 #undef LSS_RETURN
1068 #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t)
1069
1070 #undef _LSS_BODY
1071 #define _LSS_BODY(nr, type, name, cast, ...) \
1072 long long __res; \
1073 __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \
1074 : "=a" (__res) \
1075 : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \
1076 : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \
1077 _LSS_RETURN(type, __res, cast)
1078 #undef LSS_BODY
1079 #define LSS_BODY(nr, type, name, args...) \
1080 _LSS_BODY(nr, type, name, uintptr_t, ## args)
1081
1082 #undef LSS_BODY_ASM0
1083 #undef LSS_BODY_ASM1
1084 #undef LSS_BODY_ASM2
1085 #undef LSS_BODY_ASM3
1086 #undef LSS_BODY_ASM4
1087 #undef LSS_BODY_ASM5
1088 #undef LSS_BODY_ASM6
1089 #define LSS_BODY_ASM0
1090 #define LSS_BODY_ASM1 LSS_BODY_ASM0
1091 #define LSS_BODY_ASM2 LSS_BODY_ASM1
1092 #define LSS_BODY_ASM3 LSS_BODY_ASM2
1093 #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;"
1094 #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;"
1095 #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;"
1096
1097 #undef LSS_BODY_CLOBBER0
1098 #undef LSS_BODY_CLOBBER1
1099 #undef LSS_BODY_CLOBBER2
1100 #undef LSS_BODY_CLOBBER3
1101 #undef LSS_BODY_CLOBBER4
1102 #undef LSS_BODY_CLOBBER5
1103 #undef LSS_BODY_CLOBBER6
1104 #define LSS_BODY_CLOBBER0
1105 #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0
1106 #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1
1107 #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2
1108 #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10",
1109 #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8",
1110 #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9",
1111
1112 #undef LSS_BODY_ARG0
1113 #undef LSS_BODY_ARG1
1114 #undef LSS_BODY_ARG2
1115 #undef LSS_BODY_ARG3
1116 #undef LSS_BODY_ARG4
1117 #undef LSS_BODY_ARG5
1118 #undef LSS_BODY_ARG6
1119 #define LSS_BODY_ARG0()
1120 #define LSS_BODY_ARG1(arg1) \
1121 LSS_BODY_ARG0(), "D" (arg1)
1122 #define LSS_BODY_ARG2(arg1, arg2) \
1123 LSS_BODY_ARG1(arg1), "S" (arg2)
1124 #define LSS_BODY_ARG3(arg1, arg2, arg3) \
1125 LSS_BODY_ARG2(arg1, arg2), "d" (arg3)
1126 #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \
1127 LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4)
1128 #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \
1129 LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5)
1130 #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \
1131 LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6)
1132
1133 #undef _syscall0
1134 #define _syscall0(type,name) \
1135 type LSS_NAME(name)() { \
1136 LSS_BODY(0, type, name); \
1137 }
1138 #undef _syscall1
1139 #define _syscall1(type,name,type1,arg1) \
1140 type LSS_NAME(name)(type1 arg1) { \
1141 LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \
1142 }
1143 #undef _syscall2
1144 #define _syscall2(type,name,type1,arg1,type2,arg2) \
1145 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
1146 LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\
1147 }
1148 #undef _syscall3
1149 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
1150 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
1151 LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
1152 LSS_SYSCALL_ARG(arg3)); \
1153 }
1154 #undef _syscall4
1155 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
1156 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
1157 LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
1158 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\
1159 }
1160 #undef _syscall5
1161 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1162 type5,arg5) \
1163 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1164 type5 arg5) { \
1165 LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
1166 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
1167 LSS_SYSCALL_ARG(arg5)); \
1168 }
1169 #undef _syscall6
1170 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1171 type5,arg5,type6,arg6) \
1172 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1173 type5 arg5, type6 arg6) { \
1174 LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \
1175 LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \
1176 LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\
1177 }
1178 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
1179 int flags, void *arg, int *parent_tidptr,
1180 void *newtls, int *child_tidptr) {
1181 long long __res;
1182 {
1183 __asm__ __volatile__(/* if (fn == NULL)
1184 * return -EINVAL;
1185 */
1186 "testq %4,%4\n"
1187 "jz 1f\n"
1188
1189 /* if (child_stack == NULL)
1190 * return -EINVAL;
1191 */
1192 "testq %5,%5\n"
1193 "jz 1f\n"
1194
1195 /* Set up alignment of the child stack:
1196 * child_stack = (child_stack & ~0xF) - 16;
1197 */
1198 "andq $-16,%5\n"
1199 "subq $16,%5\n"
1200
1201 /* Push "arg" and "fn" onto the stack that will be
1202 * used by the child.
1203 */
1204 "movq %7,8(%5)\n"
1205 "movq %4,0(%5)\n"
1206
1207 /* %rax = syscall(%rax = __NR_clone,
1208 * %rdi = flags,
1209 * %rsi = child_stack,
1210 * %rdx = parent_tidptr,
1211 * %r8 = new_tls,
1212 * %r10 = child_tidptr)
1213 */
1214 "movq %2,%%rax\n"
1215 "movq %9,%%r8\n"
1216 "movq %10,%%r10\n"
1217 "syscall\n"
1218
1219 /* if (%rax != 0)
1220 * return;
1221 */
1222 "testq %%rax,%%rax\n"
1223 "jnz 1f\n"
1224
1225 /* In the child. Terminate frame pointer chain.
1226 */
1227 "xorq %%rbp,%%rbp\n"
1228
1229 /* Call "fn(arg)".
1230 */
1231 "popq %%rax\n"
1232 "popq %%rdi\n"
1233 "call *%%rax\n"
1234
1235 /* Call _exit(%ebx).
1236 */
1237 "movq %%rax,%%rdi\n"
1238 "movq %3,%%rax\n"
1239 "syscall\n"
1240
1241 /* Return to parent.
1242 */
1243 "1:\n"
1244 : "=a" (__res)
1245 : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
1246 "r"(LSS_SYSCALL_ARG(fn)),
1247 "S"(LSS_SYSCALL_ARG(child_stack)),
1248 "D"(LSS_SYSCALL_ARG(flags)),
1249 "r"(LSS_SYSCALL_ARG(arg)),
1250 "d"(LSS_SYSCALL_ARG(parent_tidptr)),
1251 "r"(LSS_SYSCALL_ARG(newtls)),
1252 "r"(LSS_SYSCALL_ARG(child_tidptr))
1253 : "rsp", "memory", "r8", "r10", "r11", "rcx");
1254 }
1255 LSS_RETURN(int, __res);
1256 }
1257
1258 LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {
1259 /* On x86-64, the kernel does not know how to return from
1260 * a signal handler. Instead, it relies on user space to provide a
1261 * restorer function that calls the rt_sigreturn() system call.
1262 * Unfortunately, we cannot just reference the glibc version of this
1263 * function, as glibc goes out of its way to make it inaccessible.
1264 */
1265 long long res;
1266 __asm__ __volatile__("call 2f\n"
1267 "0:.align 16\n"
1268 "1:movq %1,%%rax\n"
1269 "syscall\n"
1270 "2:popq %0\n"
1271 "addq $(1b-0b),%0\n"
1272 : "=a" (res)
1273 : "i" (__NR_rt_sigreturn));
1274 return (void (*)(void))(uintptr_t)res;
1275 }
1276 #elif defined(__arm__)
1277 /* Most definitions of _syscallX() neglect to mark "memory" as being
1278 * clobbered. This causes problems with compilers, that do a better job
1279 * at optimizing across __asm__ calls.
1280 * So, we just have to redefine all fo the _syscallX() macros.
1281 */
1282 #undef LSS_REG
1283 #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
1284
1285 /* r0..r3 are scratch registers and not preserved across function
1286 * calls. We need to first evaluate the first 4 syscall arguments
1287 * and store them on stack. They must be loaded into r0..r3 after
1288 * all function calls to avoid r0..r3 being clobbered.
1289 */
1290 #undef LSS_SAVE_ARG
1291 #define LSS_SAVE_ARG(r,a) long __tmp##r = (long)a
1292 #undef LSS_LOAD_ARG
1293 #define LSS_LOAD_ARG(r) register long __r##r __asm__("r"#r) = __tmp##r
1294
1295 #undef LSS_BODY
1296 #define LSS_BODY(type, name, args...) \
1297 register long __res_r0 __asm__("r0"); \
1298 long __res; \
1299 __SYS_REG(name) \
1300 __asm__ __volatile__ (__syscall_safe(name) \
1301 : "=r"(__res_r0) \
1302 : __SYS_REG_LIST(args) \
1303 : "lr", "memory"); \
1304 __res = __res_r0; \
1305 LSS_RETURN(type, __res)
1306 #undef _syscall0
1307 #define _syscall0(type, name) \
1308 type LSS_NAME(name)() { \
1309 LSS_BODY(type, name); \
1310 }
1311 #undef _syscall1
1312 #define _syscall1(type, name, type1, arg1) \
1313 type LSS_NAME(name)(type1 arg1) { \
1314 /* There is no need for using a volatile temp. */ \
1315 LSS_REG(0, arg1); \
1316 LSS_BODY(type, name, "r"(__r0)); \
1317 }
1318 #undef _syscall2
1319 #define _syscall2(type, name, type1, arg1, type2, arg2) \
1320 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
1321 LSS_SAVE_ARG(0, arg1); \
1322 LSS_SAVE_ARG(1, arg2); \
1323 LSS_LOAD_ARG(0); \
1324 LSS_LOAD_ARG(1); \
1325 LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
1326 }
1327 #undef _syscall3
1328 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
1329 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
1330 LSS_SAVE_ARG(0, arg1); \
1331 LSS_SAVE_ARG(1, arg2); \
1332 LSS_SAVE_ARG(2, arg3); \
1333 LSS_LOAD_ARG(0); \
1334 LSS_LOAD_ARG(1); \
1335 LSS_LOAD_ARG(2); \
1336 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
1337 }
1338 #undef _syscall4
1339 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
1340 type4, arg4) \
1341 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
1342 LSS_SAVE_ARG(0, arg1); \
1343 LSS_SAVE_ARG(1, arg2); \
1344 LSS_SAVE_ARG(2, arg3); \
1345 LSS_SAVE_ARG(3, arg4); \
1346 LSS_LOAD_ARG(0); \
1347 LSS_LOAD_ARG(1); \
1348 LSS_LOAD_ARG(2); \
1349 LSS_LOAD_ARG(3); \
1350 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
1351 }
1352 #undef _syscall5
1353 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
1354 type4, arg4, type5, arg5) \
1355 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1356 type5 arg5) { \
1357 LSS_SAVE_ARG(0, arg1); \
1358 LSS_SAVE_ARG(1, arg2); \
1359 LSS_SAVE_ARG(2, arg3); \
1360 LSS_SAVE_ARG(3, arg4); \
1361 LSS_REG(4, arg5); \
1362 LSS_LOAD_ARG(0); \
1363 LSS_LOAD_ARG(1); \
1364 LSS_LOAD_ARG(2); \
1365 LSS_LOAD_ARG(3); \
1366 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
1367 "r"(__r4)); \
1368 }
1369 #undef _syscall6
1370 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
1371 type4, arg4, type5, arg5, type6, arg6) \
1372 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1373 type5 arg5, type6 arg6) { \
1374 LSS_SAVE_ARG(0, arg1); \
1375 LSS_SAVE_ARG(1, arg2); \
1376 LSS_SAVE_ARG(2, arg3); \
1377 LSS_SAVE_ARG(3, arg4); \
1378 LSS_REG(4, arg5); \
1379 LSS_REG(5, arg6); \
1380 LSS_LOAD_ARG(0); \
1381 LSS_LOAD_ARG(1); \
1382 LSS_LOAD_ARG(2); \
1383 LSS_LOAD_ARG(3); \
1384 LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
1385 "r"(__r4), "r"(__r5)); \
1386 }
1387 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
1388 int flags, void *arg, int *parent_tidptr,
1389 void *newtls, int *child_tidptr) {
1390 register long __res __asm__("r5");
1391 {
1392 if (fn == NULL || child_stack == NULL) {
1393 __res = -EINVAL;
1394 goto clone_exit;
1395 }
1396
1397 /* stash first 4 arguments on stack first because we can only load
1398 * them after all function calls.
1399 */
1400 int tmp_flags = flags;
1401 int * tmp_stack = (int*) child_stack;
1402 void * tmp_ptid = parent_tidptr;
1403 void * tmp_tls = newtls;
1404
1405 register int *__ctid __asm__("r4") = child_tidptr;
1406
1407 /* Push "arg" and "fn" onto the stack that will be
1408 * used by the child.
1409 */
1410 *(--tmp_stack) = (int) arg;
1411 *(--tmp_stack) = (int) fn;
1412
1413 /* We must load r0..r3 last after all possible function calls. */
1414 register int __flags __asm__("r0") = tmp_flags;
1415 register void *__stack __asm__("r1") = tmp_stack;
1416 register void *__ptid __asm__("r2") = tmp_ptid;
1417 register void *__tls __asm__("r3") = tmp_tls;
1418
1419 /* %r0 = syscall(%r0 = flags,
1420 * %r1 = child_stack,
1421 * %r2 = parent_tidptr,
1422 * %r3 = newtls,
1423 * %r4 = child_tidptr)
1424 */
1425 __SYS_REG(clone)
1426 __asm__ __volatile__(/* %r0 = syscall(%r0 = flags,
1427 * %r1 = child_stack,
1428 * %r2 = parent_tidptr,
1429 * %r3 = newtls,
1430 * %r4 = child_tidptr)
1431 */
1432 "push {r7}\n"
1433 "mov r7,%1\n"
1434 __syscall(clone)"\n"
1435
1436 /* if (%r0 != 0)
1437 * return %r0;
1438 */
1439 "movs %0,r0\n"
1440 "bne 1f\n"
1441
1442 /* In the child, now. Call "fn(arg)".
1443 */
1444 "ldr r0,[sp, #4]\n"
1445 "mov lr,pc\n"
1446 "ldr pc,[sp]\n"
1447
1448 /* Call _exit(%r0), which never returns. We only
1449 * need to set r7 for EABI syscall ABI but we do
1450 * this always to simplify code sharing between
1451 * old and new syscall ABIs.
1452 */
1453 "mov r7,%2\n"
1454 __syscall(exit)"\n"
1455
1456 /* Pop r7 from the stack only in the parent.
1457 */
1458 "1: pop {r7}\n"
1459 : "=r" (__res)
1460 : "r"(__sysreg),
1461 "i"(__NR_exit), "r"(__stack), "r"(__flags),
1462 "r"(__ptid), "r"(__tls), "r"(__ctid)
1463 : "cc", "lr", "memory");
1464 }
1465 clone_exit:
1466 LSS_RETURN(int, __res);
1467 }
1468 #elif defined(__mips__)
1469 #undef LSS_REG
1470 #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
1471 (unsigned long)(a)
1472
1473 #if _MIPS_SIM == _MIPS_SIM_ABI32
1474 // See http://sources.redhat.com/ml/libc-alpha/2004-10/msg00050.html
1475 // or http://www.linux-mips.org/archives/linux-mips/2004-10/msg00142.html
1476 #define MIPS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12",\
1477 "$13", "$14", "$15", "$24", "$25", "memory"
1478 #else
1479 #define MIPS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
1480 "$14", "$15", "$24", "$25", "memory"
1481 #endif
1482
1483 #undef LSS_BODY
1484 #define LSS_BODY(type,name,r7,...) \
1485 register unsigned long __v0 __asm__("$2") = __NR_##name; \
1486 __asm__ __volatile__ ("syscall\n" \
1487 : "=&r"(__v0), r7 (__r7) \
1488 : "0"(__v0), ##__VA_ARGS__ \
1489 : MIPS_SYSCALL_CLOBBERS); \
1490 LSS_RETURN(type, __v0, __r7)
1491 #undef _syscall0
1492 #define _syscall0(type, name) \
1493 type LSS_NAME(name)() { \
1494 register unsigned long __r7 __asm__("$7"); \
1495 LSS_BODY(type, name, "=r"); \
1496 }
1497 #undef _syscall1
1498 #define _syscall1(type, name, type1, arg1) \
1499 type LSS_NAME(name)(type1 arg1) { \
1500 register unsigned long __r7 __asm__("$7"); \
1501 LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \
1502 }
1503 #undef _syscall2
1504 #define _syscall2(type, name, type1, arg1, type2, arg2) \
1505 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
1506 register unsigned long __r7 __asm__("$7"); \
1507 LSS_REG(4, arg1); LSS_REG(5, arg2); \
1508 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \
1509 }
1510 #undef _syscall3
1511 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
1512 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
1513 register unsigned long __r7 __asm__("$7"); \
1514 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1515 LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \
1516 }
1517 #undef _syscall4
1518 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
1519 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
1520 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1521 LSS_REG(7, arg4); \
1522 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \
1523 }
1524 #undef _syscall5
1525 #if _MIPS_SIM == _MIPS_SIM_ABI32
1526 /* The old 32bit MIPS system call API passes the fifth and sixth argument
1527 * on the stack, whereas the new APIs use registers "r8" and "r9".
1528 */
1529 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1530 type5,arg5) \
1531 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1532 type5 arg5) { \
1533 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1534 LSS_REG(7, arg4); \
1535 register unsigned long __v0 __asm__("$2"); \
1536 __asm__ __volatile__ (".set noreorder\n" \
1537 "lw $2, %6\n" \
1538 "subu $29, 32\n" \
1539 "sw $2, 16($29)\n" \
1540 "li $2, %2\n" \
1541 "syscall\n" \
1542 "addiu $29, 32\n" \
1543 ".set reorder\n" \
1544 : "=&r"(__v0), "+r" (__r7) \
1545 : "i" (__NR_##name), "r"(__r4), "r"(__r5), \
1546 "r"(__r6), "m" ((unsigned long)arg5) \
1547 : MIPS_SYSCALL_CLOBBERS); \
1548 LSS_RETURN(type, __v0, __r7); \
1549 }
1550 #else
1551 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1552 type5,arg5) \
1553 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1554 type5 arg5) { \
1555 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1556 LSS_REG(7, arg4); LSS_REG(8, arg5); \
1557 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
1558 "r"(__r8)); \
1559 }
1560 #endif
1561 #undef _syscall6
1562 #if _MIPS_SIM == _MIPS_SIM_ABI32
1563 /* The old 32bit MIPS system call API passes the fifth and sixth argument
1564 * on the stack, whereas the new APIs use registers "r8" and "r9".
1565 */
1566 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1567 type5,arg5,type6,arg6) \
1568 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1569 type5 arg5, type6 arg6) { \
1570 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1571 LSS_REG(7, arg4); \
1572 register unsigned long __v0 __asm__("$2"); \
1573 __asm__ __volatile__ (".set noreorder\n" \
1574 "lw $2, %6\n" \
1575 "lw $8, %7\n" \
1576 "subu $29, 32\n" \
1577 "sw $2, 16($29)\n" \
1578 "sw $8, 20($29)\n" \
1579 "li $2, %2\n" \
1580 "syscall\n" \
1581 "addiu $29, 32\n" \
1582 ".set reorder\n" \
1583 : "=&r"(__v0), "+r" (__r7) \
1584 : "i" (__NR_##name), "r"(__r4), "r"(__r5), \
1585 "r"(__r6), "r" ((unsigned long)arg5), \
1586 "r" ((unsigned long)arg6) \
1587 : MIPS_SYSCALL_CLOBBERS); \
1588 LSS_RETURN(type, __v0, __r7); \
1589 }
1590 #else
1591 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
1592 type5,arg5,type6,arg6) \
1593 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1594 type5 arg5,type6 arg6) { \
1595 LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
1596 LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \
1597 LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
1598 "r"(__r8), "r"(__r9)); \
1599 }
1600 #endif
1601 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
1602 int flags, void *arg, int *parent_tidptr,
1603 void *newtls, int *child_tidptr) {
1604 register unsigned long __v0 __asm__("$2");
1605 register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
1606 {
1607 register int __flags __asm__("$4") = flags;
1608 register void *__stack __asm__("$5") = child_stack;
1609 register void *__ptid __asm__("$6") = parent_tidptr;
1610 register int *__ctid __asm__("$8") = child_tidptr;
1611 __asm__ __volatile__(
1612 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
1613 "subu $29,24\n"
1614 #elif _MIPS_SIM == _MIPS_SIM_NABI32
1615 "sub $29,16\n"
1616 #else
1617 "dsubu $29,16\n"
1618 #endif
1619
1620 /* if (fn == NULL || child_stack == NULL)
1621 * return -EINVAL;
1622 */
1623 "li %0,%2\n"
1624 "beqz %5,1f\n"
1625 "beqz %6,1f\n"
1626
1627 /* Push "arg" and "fn" onto the stack that will be
1628 * used by the child.
1629 */
1630 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
1631 "subu %6,32\n"
1632 "sw %5,0(%6)\n"
1633 "sw %8,4(%6)\n"
1634 #elif _MIPS_SIM == _MIPS_SIM_NABI32
1635 "sub %6,32\n"
1636 "sw %5,0(%6)\n"
1637 "sw %8,8(%6)\n"
1638 #else
1639 "dsubu %6,32\n"
1640 "sd %5,0(%6)\n"
1641 "sd %8,8(%6)\n"
1642 #endif
1643
1644 /* $7 = syscall($4 = flags,
1645 * $5 = child_stack,
1646 * $6 = parent_tidptr,
1647 * $7 = newtls,
1648 * $8 = child_tidptr)
1649 */
1650 "li $2,%3\n"
1651 "syscall\n"
1652
1653 /* if ($7 != 0)
1654 * return $2;
1655 */
1656 "bnez $7,1f\n"
1657 "bnez $2,1f\n"
1658
1659 /* In the child, now. Call "fn(arg)".
1660 */
1661 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
1662 "lw $25,0($29)\n"
1663 "lw $4,4($29)\n"
1664 #elif _MIPS_SIM == _MIPS_SIM_NABI32
1665 "lw $25,0($29)\n"
1666 "lw $4,8($29)\n"
1667 #else
1668 "ld $25,0($29)\n"
1669 "ld $4,8($29)\n"
1670 #endif
1671 "jalr $25\n"
1672
1673 /* Call _exit($2)
1674 */
1675 "move $4,$2\n"
1676 "li $2,%4\n"
1677 "syscall\n"
1678
1679 "1:\n"
1680 #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
1681 "addu $29, 24\n"
1682 #elif _MIPS_SIM == _MIPS_SIM_NABI32
1683 "add $29, 16\n"
1684 #else
1685 "daddu $29,16\n"
1686 #endif
1687 : "=&r" (__v0), "=r" (__r7)
1688 : "i"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
1689 "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
1690 "r"(__ptid), "r"(__r7), "r"(__ctid)
1691 : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
1692 "$24", "memory");
1693 }
1694 LSS_RETURN(int, __v0, __r7);
1695 }
1696 #elif defined (__PPC__)
1697 #undef LSS_LOADARGS_0
1698 #define LSS_LOADARGS_0(name, dummy...) \
1699 __sc_0 = __NR_##name
1700 #undef LSS_LOADARGS_1
1701 #define LSS_LOADARGS_1(name, arg1) \
1702 LSS_LOADARGS_0(name); \
1703 __sc_3 = (unsigned long) (arg1)
1704 #undef LSS_LOADARGS_2
1705 #define LSS_LOADARGS_2(name, arg1, arg2) \
1706 LSS_LOADARGS_1(name, arg1); \
1707 __sc_4 = (unsigned long) (arg2)
1708 #undef LSS_LOADARGS_3
1709 #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \
1710 LSS_LOADARGS_2(name, arg1, arg2); \
1711 __sc_5 = (unsigned long) (arg3)
1712 #undef LSS_LOADARGS_4
1713 #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \
1714 LSS_LOADARGS_3(name, arg1, arg2, arg3); \
1715 __sc_6 = (unsigned long) (arg4)
1716 #undef LSS_LOADARGS_5
1717 #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \
1718 LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \
1719 __sc_7 = (unsigned long) (arg5)
1720 #undef LSS_LOADARGS_6
1721 #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
1722 LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \
1723 __sc_8 = (unsigned long) (arg6)
1724 #undef LSS_ASMINPUT_0
1725 #define LSS_ASMINPUT_0 "0" (__sc_0)
1726 #undef LSS_ASMINPUT_1
1727 #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3)
1728 #undef LSS_ASMINPUT_2
1729 #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4)
1730 #undef LSS_ASMINPUT_3
1731 #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5)
1732 #undef LSS_ASMINPUT_4
1733 #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6)
1734 #undef LSS_ASMINPUT_5
1735 #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7)
1736 #undef LSS_ASMINPUT_6
1737 #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8)
1738 #undef LSS_BODY
1739 #define LSS_BODY(nr, type, name, args...) \
1740 long __sc_ret, __sc_err; \
1741 { \
1742 register unsigned long __sc_0 __asm__ ("r0"); \
1743 register unsigned long __sc_3 __asm__ ("r3"); \
1744 register unsigned long __sc_4 __asm__ ("r4"); \
1745 register unsigned long __sc_5 __asm__ ("r5"); \
1746 register unsigned long __sc_6 __asm__ ("r6"); \
1747 register unsigned long __sc_7 __asm__ ("r7"); \
1748 register unsigned long __sc_8 __asm__ ("r8"); \
1749 \
1750 LSS_LOADARGS_##nr(name, args); \
1751 __asm__ __volatile__ \
1752 ("sc\n\t" \
1753 "mfcr %0" \
1754 : "=&r" (__sc_0), \
1755 "=&r" (__sc_3), "=&r" (__sc_4), \
1756 "=&r" (__sc_5), "=&r" (__sc_6), \
1757 "=&r" (__sc_7), "=&r" (__sc_8) \
1758 : LSS_ASMINPUT_##nr \
1759 : "cr0", "ctr", "memory", \
1760 "r9", "r10", "r11", "r12"); \
1761 __sc_ret = __sc_3; \
1762 __sc_err = __sc_0; \
1763 } \
1764 LSS_RETURN(type, __sc_ret, __sc_err)
1765 #undef _syscall0
1766 #define _syscall0(type, name) \
1767 type LSS_NAME(name)(void) { \
1768 LSS_BODY(0, type, name); \
1769 }
1770 #undef _syscall1
1771 #define _syscall1(type, name, type1, arg1) \
1772 type LSS_NAME(name)(type1 arg1) { \
1773 LSS_BODY(1, type, name, arg1); \
1774 }
1775 #undef _syscall2
1776 #define _syscall2(type, name, type1, arg1, type2, arg2) \
1777 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
1778 LSS_BODY(2, type, name, arg1, arg2); \
1779 }
1780 #undef _syscall3
1781 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
1782 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
1783 LSS_BODY(3, type, name, arg1, arg2, arg3); \
1784 }
1785 #undef _syscall4
1786 #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
1787 type4, arg4) \
1788 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
1789 LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \
1790 }
1791 #undef _syscall5
1792 #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
1793 type4, arg4, type5, arg5) \
1794 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1795 type5 arg5) { \
1796 LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \
1797 }
1798 #undef _syscall6
1799 #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
1800 type4, arg4, type5, arg5, type6, arg6) \
1801 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
1802 type5 arg5, type6 arg6) { \
1803 LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \
1804 }
1805 /* clone function adapted from glibc 2.18 clone.S */
1806 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
1807 int flags, void *arg, int *parent_tidptr,
1808 void *newtls, int *child_tidptr) {
1809 long __ret, __err;
1810 {
1811#if defined(__PPC64__)
1812
1813/* Stack frame offsets. */
1814#if _CALL_ELF != 2
1815#define FRAME_MIN_SIZE 112
1816#define FRAME_TOC_SAVE 40
1817#else
1818#define FRAME_MIN_SIZE 32
1819#define FRAME_TOC_SAVE 24
1820#endif
1821
1822
1823 register int (*__fn)(void *) __asm__ ("r3") = fn;
1824 register void *__cstack __asm__ ("r4") = child_stack;
1825 register int __flags __asm__ ("r5") = flags;
1826 register void * __arg __asm__ ("r6") = arg;
1827 register int * __ptidptr __asm__ ("r7") = parent_tidptr;
1828 register void * __newtls __asm__ ("r8") = newtls;
1829 register int * __ctidptr __asm__ ("r9") = child_tidptr;
1830 __asm__ __volatile__(
1831 /* check for fn == NULL
1832 * and child_stack == NULL
1833 */
1834 "cmpdi cr0, %6, 0\n\t"
1835 "cmpdi cr1, %7, 0\n\t"
1836 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
1837 "beq- cr0, 1f\n\t"
1838
1839 /* set up stack frame for child */
1840 "clrrdi %7, %7, 4\n\t"
1841 "li 0, 0\n\t"
1842 "stdu 0, -%13(%7)\n\t"
1843
1844 /* fn, arg, child_stack are saved acrVoss the syscall */
1845 "mr 28, %6\n\t"
1846 "mr 29, %7\n\t"
1847 "mr 27, %9\n\t"
1848
1849 /* syscall
1850 r3 == flags
1851 r4 == child_stack
1852 r5 == parent_tidptr
1853 r6 == newtls
1854 r7 == child_tidptr */
1855 "mr 3, %8\n\t"
1856 "mr 5, %10\n\t"
1857 "mr 6, %11\n\t"
1858 "mr 7, %12\n\t"
1859 "li 0, %4\n\t"
1860 "sc\n\t"
1861
1862 /* Test if syscall was successful */
1863 "cmpdi cr1, 3, 0\n\t"
1864 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
1865 "bne- cr1, 1f\n\t"
1866
1867 /* Do the function call */
1868 "std 2, %14(1)\n\t"
1869#if _CALL_ELF != 2
1870 "ld 0, 0(28)\n\t"
1871 "ld 2, 8(28)\n\t"
1872 "mtctr 0\n\t"
1873#else
1874 "mr 12, 28\n\t"
1875 "mtctr 12\n\t"
1876#endif
1877 "mr 3, 27\n\t"
1878 "bctrl\n\t"
1879 "ld 2, %14(1)\n\t"
1880
1881 /* Call _exit(r3) */
1882 "li 0, %5\n\t"
1883 "sc\n\t"
1884
1885 /* Return to parent */
1886 "1:\n\t"
1887 "mr %0, 3\n\t"
1888 : "=r" (__ret), "=r" (__err)
1889 : "0" (-1), "i" (EINVAL),
1890 "i" (__NR_clone), "i" (__NR_exit),
1891 "r" (__fn), "r" (__cstack), "r" (__flags),
1892 "r" (__arg), "r" (__ptidptr), "r" (__newtls),
1893 "r" (__ctidptr), "i" (FRAME_MIN_SIZE), "i" (FRAME_TOC_SAVE)
1894 : "cr0", "cr1", "memory", "ctr",
1895 "r0", "r29", "r27", "r28");
1896#else
1897 register int (*__fn)(void *) __asm__ ("r8") = fn;
1898 register void *__cstack __asm__ ("r4") = child_stack;
1899 register int __flags __asm__ ("r3") = flags;
1900 register void * __arg __asm__ ("r9") = arg;
1901 register int * __ptidptr __asm__ ("r5") = parent_tidptr;
1902 register void * __newtls __asm__ ("r6") = newtls;
1903 register int * __ctidptr __asm__ ("r7") = child_tidptr;
1904 __asm__ __volatile__(
1905 /* check for fn == NULL
1906 * and child_stack == NULL
1907 */
1908 "cmpwi cr0, %6, 0\n\t"
1909 "cmpwi cr1, %7, 0\n\t"
1910 "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t"
1911 "beq- cr0, 1f\n\t"
1912
1913 /* set up stack frame for child */
1914 "clrrwi %7, %7, 4\n\t"
1915 "li 0, 0\n\t"
1916 "stwu 0, -16(%7)\n\t"
1917
1918 /* fn, arg, child_stack are saved across the syscall: r28-30 */
1919 "mr 28, %6\n\t"
1920 "mr 29, %7\n\t"
1921 "mr 27, %9\n\t"
1922
1923 /* syscall */
1924 "li 0, %4\n\t"
1925 /* flags already in r3
1926 * child_stack already in r4
1927 * ptidptr already in r5
1928 * newtls already in r6
1929 * ctidptr already in r7
1930 */
1931 "sc\n\t"
1932
1933 /* Test if syscall was successful */
1934 "cmpwi cr1, 3, 0\n\t"
1935 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
1936 "bne- cr1, 1f\n\t"
1937
1938 /* Do the function call */
1939 "mtctr 28\n\t"
1940 "mr 3, 27\n\t"
1941 "bctrl\n\t"
1942
1943 /* Call _exit(r3) */
1944 "li 0, %5\n\t"
1945 "sc\n\t"
1946
1947 /* Return to parent */
1948 "1:\n"
1949 "mfcr %1\n\t"
1950 "mr %0, 3\n\t"
1951 : "=r" (__ret), "=r" (__err)
1952 : "0" (-1), "1" (EINVAL),
1953 "i" (__NR_clone), "i" (__NR_exit),
1954 "r" (__fn), "r" (__cstack), "r" (__flags),
1955 "r" (__arg), "r" (__ptidptr), "r" (__newtls),
1956 "r" (__ctidptr)
1957 : "cr0", "cr1", "memory", "ctr",
1958 "r0", "r29", "r27", "r28");
1959
1960#endif
1961 }
1962 LSS_RETURN(int, __ret, __err);
1963 }
1964 #elif defined(__aarch64__)
1965 #undef LSS_REG
1966 #define LSS_REG(r,a) register long __x##r __asm__("x"#r) = (long)a
1967 #undef LSS_BODY
1968 #define LSS_BODY(type,name,args...) \
1969 register long __res_x0 __asm__("x0"); \
1970 long __res; \
1971 __asm__ __volatile__ ("mov x8, %1\n" \
1972 "svc 0x0\n" \
1973 : "=r"(__res_x0) \
1974 : "i"(__NR_##name) , ## args \
1975 : "memory"); \
1976 __res = __res_x0; \
1977 LSS_RETURN(type, __res)
1978 #undef _syscall0
1979 #define _syscall0(type, name) \
1980 type LSS_NAME(name)(void) { \
1981 LSS_BODY(type, name); \
1982 }
1983 #undef _syscall1
1984 #define _syscall1(type, name, type1, arg1) \
1985 type LSS_NAME(name)(type1 arg1) { \
1986 LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__x0)); \
1987 }
1988 #undef _syscall2
1989 #define _syscall2(type, name, type1, arg1, type2, arg2) \
1990 type LSS_NAME(name)(type1 arg1, type2 arg2) { \
1991 LSS_REG(0, arg1); LSS_REG(1, arg2); \
1992 LSS_BODY(type, name, "r"(__x0), "r"(__x1)); \
1993 }
1994 #undef _syscall3
1995 #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
1996 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
1997 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
1998 LSS_BODY(type, name, "r"(__x0), "r"(__x1), "r"(__x2)); \
1999 }
2000 #undef _syscall4
2001 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
2002 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
2003 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2004 LSS_REG(3, arg4); \
2005 LSS_BODY(type, name, "r"(__x0), "r"(__x1), "r"(__x2), "r"(__x3)); \
2006 }
2007 #undef _syscall5
2008 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2009 type5,arg5) \
2010 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2011 type5 arg5) { \
2012 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2013 LSS_REG(3, arg4); LSS_REG(4, arg5); \
2014 LSS_BODY(type, name, "r"(__x0), "r"(__x1), "r"(__x2), "r"(__x3), \
2015 "r"(__x4)); \
2016 }
2017 #undef _syscall6
2018 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
2019 type5,arg5,type6,arg6) \
2020 type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
2021 type5 arg5, type6 arg6) { \
2022 LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
2023 LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
2024 LSS_BODY(type, name, "r"(__x0), "r"(__x1), "x"(__x2), "r"(__x3), \
2025 "r"(__x4), "r"(__x5)); \
2026 }
2027 /* clone function adapted from glibc 2.18 clone.S */
2028 LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
2029 int flags, void *arg, int *parent_tidptr,
2030 void *newtls, int *child_tidptr) {
2031 long __res;
2032 {
2033 register int (*__fn)(void *) __asm__("x0") = fn;
2034 register void *__stack __asm__("x1") = child_stack;
2035 register int __flags __asm__("x2") = flags;
2036 register void *__arg __asm__("x3") = arg;
2037 register int *__ptid __asm__("x4") = parent_tidptr;
2038 register void *__tls __asm__("x5") = newtls;
2039 register int *__ctid __asm__("x6") = child_tidptr;
2040 __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
2041 * return -EINVAL;
2042 */
2043 "cbz x0,1f\n"
2044 "cbz x1,1f\n"
2045
2046 /* Push "arg" and "fn" onto the stack that will be
2047 * used by the child.
2048 */
2049 "stp x0,x3, [x1, #-16]!\n"
2050
2051 "mov x0,x2\n" /* flags */
2052 "mov x2,x4\n" /* ptid */
2053 "mov x3,x5\n" /* tls */
2054 "mov x4,x6\n" /* ctid */
2055 "mov x8,%9\n" /* clone */
2056
2057 "svc 0x0\n"
2058
2059 /* if (%r0 != 0)
2060 * return %r0;
2061 */
2062 "cmp x0, #0\n"
2063 "bne 2f\n"
2064
2065 /* In the child, now. Call "fn(arg)".
2066 */
2067 "ldp x1, x0, [sp], #16\n"
2068 "blr x1\n"
2069
2070 /* Call _exit(%r0).
2071 */
2072 "mov x8, %10\n"
2073 "svc 0x0\n"
2074 "1:\n"
2075 "mov x8, %1\n"
2076 "2:\n"
2077 : "=r" (__res)
2078 : "i"(-EINVAL),
2079 "r"(__fn), "r"(__stack), "r"(__flags), "r"(__arg),
2080 "r"(__ptid), "r"(__tls), "r"(__ctid),
2081 "i"(__NR_clone), "i"(__NR_exit)
2082 : "x30", "memory");
2083 }
2084 LSS_RETURN(int, __res);
2085 }
2086 #endif
2087 #define __NR__exit __NR_exit
2088 #define __NR__gettid __NR_gettid
2089 #define __NR__mremap __NR_mremap
2090 LSS_INLINE _syscall1(int, close, int, f)
2091 LSS_INLINE _syscall1(int, _exit, int, e)
2092 LSS_INLINE _syscall3(int, fcntl, int, f,
2093 int, c, long, a)
2094 LSS_INLINE _syscall2(int, fstat, int, f,
2095 struct kernel_stat*, b)
2096 LSS_INLINE _syscall6(int, futex, int*, a,
2097 int, o, int, v,
2098 struct kernel_timespec*, t,
2099 int*, a2,
2100 int, v3)
2101#ifdef __NR_getdents64
2102 LSS_INLINE _syscall3(int, getdents64, int, f,
2103 struct kernel_dirent64*, d, int, c)
2104#define KERNEL_DIRENT kernel_dirent64
2105#define GETDENTS sys_getdents64
2106#else
2107 LSS_INLINE _syscall3(int, getdents, int, f,
2108 struct kernel_dirent*, d, int, c)
2109#define KERNEL_DIRENT kernel_dirent
2110#define GETDENTS sys_getdents
2111#endif
2112 LSS_INLINE _syscall0(pid_t, getpid)
2113 LSS_INLINE _syscall0(pid_t, getppid)
2114 LSS_INLINE _syscall0(pid_t, _gettid)
2115 LSS_INLINE _syscall2(int, kill, pid_t, p,
2116 int, s)
2117 #if defined(__x86_64__)
2118 /* Need to make sure off_t isn't truncated to 32-bits under x32. */
2119 LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) {
2120 _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o),
2121 LSS_SYSCALL_ARG(w));
2122 }
2123 #else
2124 LSS_INLINE _syscall3(off_t, lseek, int, f,
2125 off_t, o, int, w)
2126 #endif
2127 LSS_INLINE _syscall2(int, munmap, void*, s,
2128 size_t, l)
2129 LSS_INLINE _syscall5(void*, _mremap, void*, o,
2130 size_t, os, size_t, ns,
2131 unsigned long, f, void *, a)
2132 LSS_INLINE _syscall2(int, prctl, int, o,
2133 long, a)
2134 LSS_INLINE _syscall4(long, ptrace, int, r,
2135 pid_t, p, void *, a, void *, d)
2136 LSS_INLINE _syscall3(ssize_t, read, int, f,
2137 void *, b, size_t, c)
2138 LSS_INLINE _syscall4(int, rt_sigaction, int, s,
2139 const struct kernel_sigaction*, a,
2140 struct kernel_sigaction*, o, size_t, c)
2141 LSS_INLINE _syscall4(int, rt_sigprocmask, int, h,
2142 const struct kernel_sigset_t*, s,
2143 struct kernel_sigset_t*, o, size_t, c);
2144 LSS_INLINE _syscall0(int, sched_yield)
2145 LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
2146 const stack_t*, o)
2147 #if defined(__NR_fstatat)
2148 LSS_INLINE _syscall4(int, fstatat, int, d, const char *, p,
2149 struct kernel_stat*, b, int, flags)
2150 LSS_INLINE int LSS_NAME(stat)(const char* p, struct kernel_stat* b) {
2151 return LSS_NAME(fstatat)(AT_FDCWD,p,b,0);
2152 }
2153 #else
2154 LSS_INLINE _syscall2(int, stat, const char*, f,
2155 struct kernel_stat*, b)
2156 #endif
2157 LSS_INLINE _syscall3(ssize_t, write, int, f,
2158 const void *, b, size_t, c)
2159 #if defined(__NR_getcpu)
2160 LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
2161 unsigned *, node, void *, unused);
2162 #endif
2163 #if defined(__x86_64__) || defined(__aarch64__) || \
2164 (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
2165 LSS_INLINE _syscall3(int, socket, int, d,
2166 int, t, int, p)
2167 #endif
2168 #if defined(__x86_64__)
2169 /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */
2170 LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d,
2171 __off64_t o) {
2172 LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l),
2173 LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f),
2174 LSS_SYSCALL_ARG(d), (uint64_t)(o));
2175 }
2176
2177 LSS_INLINE int LSS_NAME(sigaction)(int signum,
2178 const struct kernel_sigaction *act,
2179 struct kernel_sigaction *oldact) {
2180 /* On x86_64, the kernel requires us to always set our own
2181 * SA_RESTORER in order to be able to return from a signal handler.
2182 * This function must have a "magic" signature that the "gdb"
2183 * (and maybe the kernel?) can recognize.
2184 */
2185 if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
2186 struct kernel_sigaction a = *act;
2187 a.sa_flags |= SA_RESTORER;
2188 a.sa_restorer = LSS_NAME(restore_rt)();
2189 return LSS_NAME(rt_sigaction)(signum, &a, oldact,
2190 (KERNEL_NSIG+7)/8);
2191 } else {
2192 return LSS_NAME(rt_sigaction)(signum, act, oldact,
2193 (KERNEL_NSIG+7)/8);
2194 }
2195 }
2196
2197 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
2198 const struct kernel_sigset_t *set,
2199 struct kernel_sigset_t *oldset) {
2200 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
2201 }
2202 #endif
2203 #if (defined(__aarch64__)) || \
2204 (defined(__mips__) && (_MIPS_ISA == _MIPS_ISA_MIPS64))
2205 LSS_INLINE _syscall6(void*, mmap, void*, s,
2206 size_t, l, int, p,
2207 int, f, int, d,
2208 __off64_t, o)
2209 LSS_INLINE int LSS_NAME(sigaction)(int signum,
2210 const struct kernel_sigaction *act,
2211 struct kernel_sigaction *oldact) {
2212 return LSS_NAME(rt_sigaction)(signum, act, oldact, (KERNEL_NSIG+7)/8);
2213
2214 }
2215 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
2216 const struct kernel_sigset_t *set,
2217 struct kernel_sigset_t *oldset) {
2218 return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
2219 }
2220 #endif
2221 #ifdef __NR_wait4
2222 LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
2223 int*, s, int, o,
2224 struct kernel_rusage*, r)
2225 LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){
2226 return LSS_NAME(wait4)(pid, status, options, 0);
2227 }
2228 #else
2229 LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
2230 int*, s, int, o)
2231 #endif
2232 #ifdef __NR_openat
2233 LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
2234 LSS_INLINE int LSS_NAME(open)(const char* p, int f, int m) {
2235 return LSS_NAME(openat)(AT_FDCWD,p,f,m );
2236 }
2237 #else
2238 LSS_INLINE _syscall3(int, open, const char*, p,
2239 int, f, int, m)
2240 #endif
2241 LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
2242 memset(&set->sig, 0, sizeof(set->sig));
2243 return 0;
2244 }
2245
2246 LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {
2247 memset(&set->sig, -1, sizeof(set->sig));
2248 return 0;
2249 }
2250
2251 LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,
2252 int signum) {
2253 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
2254 LSS_ERRNO = EINVAL;
2255 return -1;
2256 } else {
2257 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
2258 |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0])));
2259 return 0;
2260 }
2261 }
2262
2263 LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,
2264 int signum) {
2265 if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {
2266 LSS_ERRNO = EINVAL;
2267 return -1;
2268 } else {
2269 set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]
2270 &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0]))));
2271 return 0;
2272 }
2273 }
2274
2275 #if defined(__i386__) || \
2276 defined(__arm__) || \
2277 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || defined(__PPC__)
2278 #define __NR__sigaction __NR_sigaction
2279 #define __NR__sigprocmask __NR_sigprocmask
2280 LSS_INLINE _syscall2(int, fstat64, int, f,
2281 struct kernel_stat64 *, b)
2282 LSS_INLINE _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
2283 loff_t *, res, uint, wh)
2284#ifdef __PPC64__
2285 LSS_INLINE _syscall6(void*, mmap, void*, s,
2286 size_t, l, int, p,
2287 int, f, int, d,
2288 off_t, o)
2289#else
2290 #ifndef __ARM_EABI__
2291 /* Not available on ARM EABI Linux. */
2292 LSS_INLINE _syscall1(void*, mmap, void*, a)
2293 #endif
2294 LSS_INLINE _syscall6(void*, mmap2, void*, s,
2295 size_t, l, int, p,
2296 int, f, int, d,
2297 off_t, o)
2298#endif
2299 LSS_INLINE _syscall3(int, _sigaction, int, s,
2300 const struct kernel_old_sigaction*, a,
2301 struct kernel_old_sigaction*, o)
2302 LSS_INLINE _syscall3(int, _sigprocmask, int, h,
2303 const unsigned long*, s,
2304 unsigned long*, o)
2305 LSS_INLINE _syscall2(int, stat64, const char *, p,
2306 struct kernel_stat64 *, b)
2307
2308 LSS_INLINE int LSS_NAME(sigaction)(int signum,
2309 const struct kernel_sigaction *act,
2310 struct kernel_sigaction *oldact) {
2311 int old_errno = LSS_ERRNO;
2312 int rc;
2313 struct kernel_sigaction a;
2314 if (act != NULL) {
2315 a = *act;
2316 #ifdef __i386__
2317 /* On i386, the kernel requires us to always set our own
2318 * SA_RESTORER when using realtime signals. Otherwise, it does not
2319 * know how to return from a signal handler. This function must have
2320 * a "magic" signature that the "gdb" (and maybe the kernel?) can
2321 * recognize.
2322 * Apparently, a SA_RESTORER is implicitly set by the kernel, when
2323 * using non-realtime signals.
2324 *
2325 * TODO: Test whether ARM needs a restorer
2326 */
2327 if (!(a.sa_flags & SA_RESTORER)) {
2328 a.sa_flags |= SA_RESTORER;
2329 a.sa_restorer = (a.sa_flags & SA_SIGINFO)
2330 ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();
2331 }
2332 #endif
2333 }
2334 rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,
2335 (KERNEL_NSIG+7)/8);
2336 if (rc < 0 && LSS_ERRNO == ENOSYS) {
2337 struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;
2338 if (!act) {
2339 ptr_a = NULL;
2340 } else {
2341 oa.sa_handler_ = act->sa_handler_;
2342 memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));
2343 #ifndef __mips__
2344 oa.sa_restorer = act->sa_restorer;
2345 #endif
2346 oa.sa_flags = act->sa_flags;
2347 }
2348 if (!oldact) {
2349 ptr_oa = NULL;
2350 }
2351 LSS_ERRNO = old_errno;
2352 rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);
2353 if (rc == 0 && oldact) {
2354 if (act) {
2355 memcpy(oldact, act, sizeof(*act));
2356 } else {
2357 memset(oldact, 0, sizeof(*oldact));
2358 }
2359 oldact->sa_handler_ = ptr_oa->sa_handler_;
2360 oldact->sa_flags = ptr_oa->sa_flags;
2361 memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));
2362 #ifndef __mips__
2363 oldact->sa_restorer = ptr_oa->sa_restorer;
2364 #endif
2365 }
2366 }
2367 return rc;
2368 }
2369
2370 LSS_INLINE int LSS_NAME(sigprocmask)(int how,
2371 const struct kernel_sigset_t *set,
2372 struct kernel_sigset_t *oldset) {
2373 int olderrno = LSS_ERRNO;
2374 int rc = LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
2375 if (rc < 0 && LSS_ERRNO == ENOSYS) {
2376 LSS_ERRNO = olderrno;
2377 if (oldset) {
2378 LSS_NAME(sigemptyset)(oldset);
2379 }
2380 rc = LSS_NAME(_sigprocmask)(how,
2381 set ? &set->sig[0] : NULL,
2382 oldset ? &oldset->sig[0] : NULL);
2383 }
2384 return rc;
2385 }
2386 #endif
2387 #if defined(__i386__) || \
2388 defined(__PPC__) || \
2389 (defined(__arm__) && !defined(__ARM_EABI__)) || \
2390 (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
2391
2392 /* See sys_socketcall in net/socket.c in kernel source.
2393 * It de-multiplexes on its first arg and unpacks the arglist
2394 * array in its second arg.
2395 */
2396 LSS_INLINE _syscall2(long, socketcall, int, c, unsigned long*, a)
2397
2398 LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
2399 unsigned long args[3] = {
2400 (unsigned long) domain,
2401 (unsigned long) type,
2402 (unsigned long) protocol
2403 };
2404 return LSS_NAME(socketcall)(1, args);
2405 }
2406 #elif defined(__ARM_EABI__)
2407 LSS_INLINE _syscall3(int, socket, int, d,
2408 int, t, int, p)
2409 #endif
2410 #if defined(__mips__)
2411 /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
2412 * both file handles through CPU registers.
2413 */
2414 LSS_INLINE int LSS_NAME(pipe)(int *p) {
2415 register unsigned long __v0 __asm__("$2") = __NR_pipe;
2416 register unsigned long __v1 __asm__("$3");
2417 register unsigned long __r7 __asm__("$7");
2418 __asm__ __volatile__ ("syscall\n"
2419 : "=&r"(__v0), "=&r"(__v1), "+r" (__r7)
2420 : "0"(__v0)
2421 : "$8", "$9", "$10", "$11", "$12",
2422 "$13", "$14", "$15", "$24", "memory");
2423 if (__r7) {
2424 LSS_ERRNO = __v0;
2425 return -1;
2426 } else {
2427 p[0] = __v0;
2428 p[1] = __v1;
2429 return 0;
2430 }
2431 }
2432 #elif defined(__NR_pipe2)
2433 LSS_INLINE _syscall2(int, pipe2, int *, p,
2434 int, f )
2435 LSS_INLINE int LSS_NAME(pipe)( int * p) {
2436 return LSS_NAME(pipe2)(p, 0);
2437 }
2438 #else
2439 LSS_INLINE _syscall1(int, pipe, int *, p)
2440 #endif
2441
2442 LSS_INLINE pid_t LSS_NAME(gettid)() {
2443 pid_t tid = LSS_NAME(_gettid)();
2444 if (tid != -1) {
2445 return tid;
2446 }
2447 return LSS_NAME(getpid)();
2448 }
2449
2450 LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
2451 size_t new_size, int flags, ...) {
2452 va_list ap;
2453 void *new_address, *rc;
2454 va_start(ap, flags);
2455 new_address = va_arg(ap, void *);
2456 rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
2457 flags, new_address);
2458 va_end(ap);
2459 return rc;
2460 }
2461
2462 LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) {
2463 /* PTRACE_DETACH can sometimes forget to wake up the tracee and it
2464 * then sends job control signals to the real parent, rather than to
2465 * the tracer. We reduce the risk of this happening by starting a
2466 * whole new time slice, and then quickly sending a SIGCONT signal
2467 * right after detaching from the tracee.
2468 */
2469 int rc, err;
2470 LSS_NAME(sched_yield)();
2471 rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
2472 err = LSS_ERRNO;
2473 LSS_NAME(kill)(pid, SIGCONT);
2474 LSS_ERRNO = err;
2475 return rc;
2476 }
2477#endif
2478
2479#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
2480}
2481#endif
2482
2483#endif
2484#endif