/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- mtcp_abort
1 /*****************************************************************************
2 * Copyright (C) 2006-2008 Michael Rieker <mrieker@nii.net> *
3 * Copyright (C) 2014 Kapil Arya <kapil@ccs.neu.edu> *
4 * Copyright (C) 2014 Gene Cooperman <gene@ccs.neu.edu> *
5 * *
6 * DMTCP is free software: you can redistribute it and/or *
7 * modify it under the terms of the GNU Lesser General Public License as *
8 * published by the Free Software Foundation, either version 3 of the *
9 * License, or (at your option) any later version. *
10 * *
11 * DMTCP is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU Lesser General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU Lesser General Public *
17 * License along with DMTCP. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
19
20 /* README!!!!
21 * For ARM, you can ignore almost all of this code. Only the
22 * mtcp_sys_XXX() macros are needed for ARM, along with the code at the end
23 * of this file that overrides the definition of mtcp_inline_syscall(),
24 * which directly calls syscall, defined in syscall-arm.S.
25 * Even the name mtcp_inline_syscall() is bad, now that we call
26 * a syscall function defined in syscall-arm.S.
27 * After the DMTCP-2.2 release, we will do the same thing for Intel.
28 */
29
30 /*
31 * The goal of including this file is to define most of the external
32 * symbols used in mtcp_sharetemp.c . This to insure that the linker
33 * does not try to resolve any symbols by linking in libc. That would
34 * fail at restart time, when there is no libc.
35 * mtcp_sharetemp.c is a concatenation
36 * of other files, allowing us to compile a single file into a static
37 * object. (Is it still necessary to use sharetemp.c?)
38 *
39 *Could have used ideas from statifier?:
40 * http://statifier.sourceforge.net/
41 *But that still depends too much on ELF
42 *At least it has information on changing initialization, which we can use
43 * later to remove the requirement to add a line to the `main' routine.
44 *
45 * Note that /usr/include/asm/unistd.h defines syscall using either:
46 * /usr/include/asm-i386/unistd.h
47 * or:
48 * /usr/include/asm-x86_64/unistd.h
49 */
50
51 #ifndef _MTCP_SYS_H
52 #define _MTCP_SYS_H
53
54 #include <stdio.h>
55 #include <asm/unistd.h>
56 #include <sys/types.h>
57 #include <sys/stat.h>
58 #include <unistd.h>
59 #include <fcntl.h>
60 #include <sys/mman.h>
61 #include <linux/version.h>
62 #include <sys/syscall.h> /* For SYS_xxx definitions needed in expansions. */
63
64 // Source code is taken from: glibc-2.5/sysdeps/generic
65 /* Type to use for aligned memory operations.
66 This should normally be the biggest type supported by a single load
67 and store. */
68 #undef opt_t
69 #undef OPSIZ
70 #undef __ptr_t
71 //#define op_t unsigned long int
72 //#define OPSIZ (sizeof(op_t))
73 //# define __ptr_t void *
74
75 /* Type to use for unaligned operations. */
76 //typedef unsigned char byte;
77
78 /* Optimal type for storing bytes in registers. */
79 //#define reg_char char
80
81
82 //======================================================================
83
84 // Rename it for cosmetic reasons. We export mtcp_inline_syscall.
85 // In gcc-4.8, we now need "<space>, ##args" below.
86 // SEE: http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
87 #define mtcp_inline_syscall(name, num_args, args...) \
88 INLINE_SYSCALL(name, num_args , ##args)
89
90 /* We allocate this in mtcp_safemmap.c. Files using mtcp_sys.h
91 * are also linking with mtcp_safemmap.c.
92 */
93 extern int mtcp_sys_errno;
94
95 // Define INLINE_SYSCALL. In i386, need patch for 6 args
96
97 // sysdep-x86_64.h:
98 // From glibc-2.5/sysdeps/unix/sysv/linux/x86_64/sysdep.h:
99 // (define INLINE_SYSCALL)
100 // sysdep-i386.h:
101 // Or glibc-2.5/sysdeps/unix/sysv/linux/i386/sysdep.h: (define INLINE_SYSCALL)
102 // But all further includes from sysdep-XXX.h have been commented out.
103
104 #ifdef __i386__
105 /* AFTER DMTCP RELEASE 1.2.5, MAKE USE_PROC_MAPS CASE THE ONLY CASE AND DO:
106 * mv sysdep-i386-new.h sysdep-i386.h
107 */
108 // THIS CASE fOR i386 NEEDS PATCHING FOR 6 ARGUMENT CASE, SUCH AS MMAP.
109 // IT ONLY TRIES TO HANDLE UP TO 5 ARGS.
110 # include "sysdep/sysdep-i386.h"
111
112 # ifndef __PIC__
113 // NOTE: Some misinformation on web and newer glibc:sysdep-i386.h says 6-arg
114 // syscalls use: eax, ebx, ecx, edx, esi, edi, ebp
115 // Maybe this was true historically, but it really uses eax for syscall
116 // number, and sets ebx to point to the 6 args (which typically are on stack).
117 # define EXTRAVAR_6
118 # define LOADARGS_6 \
119 "sub $24,%%esp; mov %2,(%%esp); mov %3,4(%%esp); mov %4,8(%%esp);" \
120 " mov %5,12(%%esp); mov %6,16(%%esp); mov %7,20(%%esp);" \
121 " mov %%esp,%%ebx\n\t" /* sysdep-i386 then does: mov %1,%%eax */
122 # define RESTOREARGS_6 \
123 RESTOREARGS_5 \
124 "add $24,%%esp\n\t"
125 # define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
126 ASMFMT_5(arg1, arg2, arg3, arg4, arg5), "0" (arg6)
127 # else
128 // TO SEE EXAMPLES OF MACROS, TRY:
129 // cpp -fPIC -DPIC -dM mtcp_safemmap.c | grep '_5 '
130 // MODEL TEMPLATE IN sysdep-i386.h:
131 // #define INTERNAL_SYSCALL(name, err, nr, args...)
132 // ({
133 // register unsigned int resultvar;
134 // EXTRAVAR_##nr
135 // asm volatile (
136 // LOADARGS_##nr
137 // "movl %1, %%eax\n\t"
138 // "int $0x80\n\t"
139 // RESTOREARGS_##nr
140 // : "=a" (resultvar)
141 // : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc");
142 // (int) resultvar; })
143 // PIC uses ebp as base pointer for variables. Save it last, retore it first.
144 #if 0
145 # define EXTRAVAR_6 int _xv1, _xv2;
146 # define LOADARGS_6 LOADARGS_5 "movl %%esp, %4\n\t" "movl %%ebp, %%esp\n\t" "movl %9, %%ebp\n\t"
147 # define RESTOREARGS_6 "movl %%esp, %%ebp\n\t" "movl %4, %%esp\n\t" RESTOREARGS_5
148 # define ASMFMT_6(arg1,arg2,arg3,arg4,arg5,arg6) , "0" (arg1), "m" (_xv1), "m" (_xv2), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "rm" (arg6)
149 #else
150 // NOTE: Some misinformation on web and newer glibc:sysdep-i386.h says 6-arg
151 // syscalls use: eax, ebx, ecx, edx, esi, edi, ebp
152 // Maybe this was true historically, but it really uses eax for syscall
153 // number, and sets ebx to point to the 6 args (which typically are on stack).
154 // eax is free register, since it is set to syscall number just before: int 0x80
155 # define EXTRAVAR_6
156 # define LOADARGS_6 \
157 "sub $28,%%esp; mov %2,(%%esp); mov %3,4(%%esp); mov %4,8(%%esp);" \
158 " mov %5,12(%%esp); mov %6,16(%%esp); mov %7,%%eax; mov %%eax,20(%%esp);" \
159 " mov %%ebx,24(%%esp); mov %%esp,%%ebx\n\t" \
160 /* sysdep-i386 then does: mov %1,%%eax */
161 # define RESTOREARGS_6 "mov 24(%%esp),%%ebx\n\t" "add $28,%%esp\n\t"
162 /*
163 # define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
164 ASMFMT_5(arg1, arg2, arg3, arg4, arg5), "rm" (arg6)
165 */
166 # define ASMFMT_6(arg1,arg2,arg3,arg4,arg5,arg6) , "0" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "rm" (arg6)
167 #endif
168 # endif
169
170 #elif __x86_64__
171 # include "sysdep/sysdep-x86_64.h"
172
173 #elif __arm__
174 // COPIED FROM: glibc-ports-2.14/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h
175 // In turn, this calls "sysdep-arm.h" from .../linux/arm/sysdep.h
176 // We are removing this dependency, now that we're introducing syscall-arm.S
177 // In the future, we'll do the same for i386 and x86_64 to simplify the logic.
178 // # include "sysdep/sysdep-arm-eabi.h"
179
180 #elif defined(__aarch64__)
181 // FIXME: Now that we're introducing syscall-aarch64.S, we should abandon this.
182 //# include "sysdep-aarch64.h"
183 #else
184 # error "Missing sysdep.h file for this architecture."
185 #endif /* end __arm__ */
186
187 // FIXME: Get rid of mtcp_sys_errno
188 // Must first define multi-threaded errno when glibc not present.
189 #define __set_errno(Val) ( mtcp_sys_errno = (Val) ) /* required for sysdep-XXX.h */
190 // #define __set_errno(Val) ( errno = mtcp_sys_errno = (Val) ) /* required for sysdep-XXX.h */
191
192 // #include <sysdeps/unix/x86_64/sysdep.h> is not needed.
193 // translate __NR_getpid to syscall # using i386 or x86_64
194 #include <asm/unistd.h>
195
196 /* getdents() fills up the buffer not with 'struct dirent's as might be
197 * expected, but with custom 'struct linux_dirent's. This structure, however,
198 * must be manually defined. This definition is taken from the getdents(2) man
199 * page.
200 */
201 struct linux_dirent {
202 long d_ino;
203 off_t d_off;
204 unsigned short d_reclen;
205 char d_name[];
206 };
207
208 //==================================================================
209
210 /* USAGE: mtcp_inline_syscall: second arg is number of args of system call */
211 #define mtcp_sys_read(args...) mtcp_inline_syscall(read,3,args)
212 #define mtcp_sys_write(args...) mtcp_inline_syscall(write,3,args)
213 #define mtcp_sys_lseek(args...) mtcp_inline_syscall(lseek,3,args)
214
215 /*
216 * As of glibc-2.18, open() has been replaced by openat(). glibc converts
217 * calls to open() to openat(), but NOT for Aarch64
218 */
219 #if defined(__aarch64__)
220 # define mtcp_sys_open(args...) mtcp_inline_syscall(openat,4,AT_FDCWD,args)
221 #else
222 # define mtcp_sys_open(args...) mtcp_inline_syscall(open,3,args)
223 #endif
224
225 // mode must be specified when O_CREAT is in the flags, and is ignored
226 // otherwise.
227 #define mtcp_sys_open2(args...) mtcp_sys_open(args,0777)
228 #define mtcp_sys_ftruncate(args...) mtcp_inline_syscall(ftruncate,2,args)
229 #define mtcp_sys_close(args...) mtcp_inline_syscall(close,1,args)
230 #if defined(__aarch64__)
231 # define mtcp_sys_access(path,mode) \
232 mtcp_inline_syscall(faccessat,4,AT_FDCWD,path,mode,AT_EACCESS)
233 # define mtcp_sys_unlink(path) mtcp_inline_syscall(unlinkat,3,AT_FDCWD, path, 0)
234 #else
235 # define mtcp_sys_unlink(args...) mtcp_inline_syscall(unlink,1,args)
236 # define mtcp_sys_access(args...) mtcp_inline_syscall(access,2,args)
237 #endif
238 #define mtcp_sys_fchmod(args...) mtcp_inline_syscall(fchmod,2,args)
239 #if defined(__aarch64__)
240 # define mtcp_sys_rename(oldpath,newpath) \
241 mtcp_inline_syscall(renameat,4,AT_FDCWD,oldpath,AT_FDCWD,newpath)
242 #else
243 # define mtcp_sys_rename(args...) mtcp_inline_syscall(rename,2,args)
244 #endif
245 #define mtcp_sys_exit(args...) mtcp_inline_syscall(exit,1,args)
246 #if defined(__aarch64__)
247 # define mtcp_sys_pipe(fd) mtcp_inline_syscall(pipe2,2,fd,0)
248 #else
249 # define mtcp_sys_pipe(args...) mtcp_inline_syscall(pipe,1,args)
250 #endif
251 #define mtcp_sys_dup(args...) mtcp_inline_syscall(dup,1,args)
252 #if defined(__aarch64__)
253 # define mtcp_sys_dup2(oldfd,newfd) \
254 mtcp_inline_syscall(dup3,3,oldfd,newfd,NULL)
255 #else
256 # define mtcp_sys_dup2(args...) mtcp_inline_syscall(dup2,2,args)
257 #endif
258 #define mtcp_sys_getpid(args...) mtcp_inline_syscall(getpid,0)
259 #define mtcp_sys_getppid(args...) mtcp_inline_syscall(getppid,0)
260 #if defined(__aarch64__)
261 # define mtcp_sys_fork(args...) \
262 mtcp_inline_syscall(clone,4,SIGCHLD,NULL,NULL,NULL)
263 #else
264 # define mtcp_sys_fork(args...) mtcp_inline_syscall(fork,0)
265 #endif
266 #define mtcp_sys_vfork(args...) mtcp_inline_syscall(vfork,0)
267 #define mtcp_sys_execve(args...) mtcp_inline_syscall(execve,3,args)
268 #define mtcp_sys_wait4(args...) mtcp_inline_syscall(wait4,4,args)
269 #define mtcp_sys_gettimeofday(args...) mtcp_inline_syscall(gettimeofday,2,args)
270 #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
271 # define mtcp_sys_mmap(args...) (void *)mtcp_inline_syscall(mmap,6,args)
272 #elif defined(__arm__)
273 /* ARM Linux kernel doesn't support mmap: translate to newer mmap2 */
274 # define mtcp_sys_mmap(addr,length,prot,flags,fd,offset) \
275 (void *)mtcp_inline_syscall(mmap2,6,addr,length,prot,flags,fd,offset/4096)
276 #elif defined(__aarch64__)
277 # define mtcp_sys_mmap(args...) (void *)mtcp_inline_syscall(mmap,6,args)
278 #else
279 # error "getrlimit kernel call not implemented in this architecture"
280 #endif
281 #define mtcp_sys_mremap(args...) (void *)mtcp_inline_syscall(mremap,5,args)
282 #define mtcp_sys_munmap(args...) mtcp_inline_syscall(munmap,2,args)
283 #define mtcp_sys_mprotect(args...) mtcp_inline_syscall(mprotect,3,args)
284 #define mtcp_sys_nanosleep(args...) mtcp_inline_syscall(nanosleep,2,args)
285 #define mtcp_sys_brk(args...) (void *)(mtcp_inline_syscall(brk,1,args))
286 #define mtcp_sys_rt_sigaction(args...) mtcp_inline_syscall(rt_sigaction,4,args)
287 #define mtcp_sys_set_tid_address(args...) \
288 mtcp_inline_syscall(set_tid_address,1,args)
289
290 //#define mtcp_sys_stat(args...) mtcp_inline_syscall(stat, 2, args)
291 #define mtcp_sys_getuid(args...) mtcp_inline_syscall(getuid, 0)
292 #define mtcp_sys_geteuid(args...) mtcp_inline_syscall(geteuid, 0)
293
294 #define mtcp_sys_personality(args...) mtcp_inline_syscall(personality, 1, args)
295 #if defined(__aarch64__)
296 // As of glibc-2.18, readlink() has been replaced by readlinkat()
297 // glibc includes checks for old call, except in Aarch64
298 # define mtcp_sys_readlink(args...) mtcp_inline_syscall(readlinkat, 3, args)
299 #else
300 # define mtcp_sys_readlink(args...) mtcp_inline_syscall(readlink, 3, args)
301 #endif
302 #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
303 /* Should this be changed to use newer ugetrlimit kernel call? */
304 # define mtcp_sys_getrlimit(args...) mtcp_inline_syscall(getrlimit, 2, args)
305 #elif defined(__arm__)
306 /* EABI ARM exclusively uses newer ugetrlimit kernel API, and not getrlimit */
307 # define mtcp_sys_getrlimit(args...) mtcp_inline_syscall(ugetrlimit, 2, args)
308 #elif defined(__aarch64__)
309 # define mtcp_sys_getrlimit(args...) mtcp_inline_syscall(getrlimit, 2, args)
310 #else
311 # error "getrlimit kernel call not implemented in this architecture"
312 #endif
313 #define mtcp_sys_setrlimit(args...) mtcp_inline_syscall(setrlimit, 2, args)
314
315 #ifdef __NR_getdents
316 #define mtcp_sys_getdents(args...) mtcp_inline_syscall(getdents,3,args)
317 /* Note that getdents() does not fill the buf with 'struct dirent's, but
318 * instead with 'struct linux_dirent's. These must be defined manually, and
319 * in our case have been defined earlier in this file. */
320 #endif
321 #ifdef __NR_getdents64
322 #define mtcp_sys_getdents64(args...) mtcp_inline_syscall(getdents64,3,args)
323 #endif
324
325 #define mtcp_sys_fcntl2(args...) mtcp_inline_syscall(fcntl,2,args)
326 #define mtcp_sys_fcntl3(args...) mtcp_inline_syscall(fcntl,3,args)
327 #if defined(__aarch64__)
328 # define mtcp_sys_mkdir(args...) mtcp_inline_syscall(mkdirat,3,AT_FDCWD,args)
329 #else
330 # define mtcp_sys_mkdir(args...) mtcp_inline_syscall(mkdir,2,args)
331 #endif
332
333 #ifdef __i386__
334 # define mtcp_sys_get_thread_area(args...) \
335 mtcp_inline_syscall(get_thread_area,1,args)
336 # define mtcp_sys_set_thread_area(args...) \
337 mtcp_inline_syscall(set_thread_area,1,args)
338 #endif
339
340 #if defined(__aarch64__)
341 // FIXME: Is this code still needed?
342 # ifdef MTCP_SYS_GET_SET_THREAD_AREA
343
344 static unsigned int myinfo_gs;
345
346 # define mtcp_sys_get_thread_area(uinfo) \
347 ({ asm volatile ("mrs %0, tpidr_el0" \
348 : "=r" (myinfo_gs) ); \
349 myinfo_gs = myinfo_gs - 1216; /* sizeof(struct pthread) = 1216 */ \
350 *(unsigned long int *)&(((struct user_desc *)uinfo)->base_addr) \
351 = myinfo_gs; \
352 myinfo_gs; })
353 # define mtcp_sys_set_thread_area(uinfo) \
354 ({ myinfo_gs = \
355 *(unsigned long int *)&(((struct user_desc *)uinfo)->base_addr); \
356 myinfo_gs = myinfo_gs + 1216; \
357 asm volatile ("msr tpidr_el0, %[gs]" : : [gs] "r" (myinfo_gs) ); \
358 0; })
359 # endif /* end MTCP_SYS_GET_SET_THREAD_AREA */
360 #endif /* end __aarch64__ */
361
362 /*****************************************************************************
363 * mtcp_sys_kernel_XXX() indicates it's particular to Linux, or glibc uses
364 * a different version than the kernel version of the function.
365 *
366 * NOTE: this calls kernel version of stat, not the glibc wrapper for stat
367 * Needs: glibc_kernel_stat.h = glibc-2.5/sysdeps/unix/sysv/linux/kernel_stat.h
368 * for sake of st_mode, st_def, st_inode fields.
369 * For: int stat(const char *file_name, struct kernel_stat *buf);
370 * For: int lstat(const char *file_name, struct kernel_stat *buf);
371 *
372 * See glibc:/var/tmp/cooperma/glibc-2.5/sysdeps/unix/sysv/linux/i386/lxstat.c
373 * for other concerns about using stat in a 64-bit environment.
374 *****************************************************************************/
375
376 /* NOTE: MTCP no longer needs the following two mtcp_sys_kernel_stat so
377 * commenting them out. --Kapil
378 *
379 * #define mtcp_sys_kernel_stat(args...) mtcp_inline_syscall(stat,2,args)
380 * #define mtcp_sys_kernel_lstat(args...) mtcp_inline_syscall(lstat,2,args)
381 */
382
383 /* NOTE: this calls kernel version of futex, not glibc sys_futex ("man futex")
384 * There is no library supporting futex. Syscall is the only way to call it.
385 * For: int futex(int *uaddr, int op, int val,
386 * const struct timespec *timeout, int *uaddr2, int val3)
387 * "man 2 futex" and "man 4/7 futex" have limited descriptions.
388 * mtcp_internal.h has the macro defines used with futex.
389 */
390 #define mtcp_sys_kernel_futex(args...) mtcp_inline_syscall(futex,6,args)
391
392 /* NOTE: this calls kernel version of gettid, not glibc gettid ("man gettid")
393 * There is no library supporting gettid. Syscall is the only way to call it.
394 * For: pid_t gettid(void);
395 */
396 #define mtcp_sys_kernel_gettid(args...) mtcp_inline_syscall(gettid,0)
397
398 /* NOTE: this calls kernel version of tkill, not glibc tkill ("man tkill")
399 * There is no library supporting tkill. Syscall is the only way to call it.
400 * For: pid_t tkill(void);
401 */
402 #define mtcp_sys_kernel_tkill(args...) mtcp_inline_syscall(tkill,2,args)
403 #define mtcp_sys_kernel_tgkill(args...) mtcp_inline_syscall(tgkill,3,args)
404
405 #if defined(__arm__)
406 /* NOTE: set_tls is an ARM-specific call, with only a kernel API.
407 * We use the _RAW form; otherwise, set_tls would expand to __SYS_set_tls
408 * This is a modification of sysdep-arm.h:INLINE_SYSCALL()
409 */
410 # define INLINE_SYSCALL_RAW(name, nr, args...) \
411 ({ unsigned int _sys_result = INTERNAL_SYSCALL_RAW (name, , nr, args);\
412 if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_sys_result, ), 0))\
413 { \
414 __set_errno (INTERNAL_SYSCALL_ERRNO (_sys_result, )); \
415 _sys_result = (unsigned int) -1; \
416 } \
417 (int) _sys_result; })
418 /* Next macro uses 'mcr', a kernel-mode instr. on ARM */
419 # define mtcp_sys_kernel_set_tls(args...) \
420 INLINE_SYSCALL_RAW(__ARM_NR_set_tls,1,args)
421 #endif
422
423 //==================================================================
424
425 #ifdef __x86_64__
426 # define eax rax
427 # define ebx rbx
428 # define ecx rcx
429 # define edx rax
430 # define ebp rbp
431 # define esi rsi
432 # define edi rdi
433 # define esp rsp
434 # define CLEAN_FOR_64_BIT(args...) CLEAN_FOR_64_BIT_HELPER(args)
435 # define CLEAN_FOR_64_BIT_HELPER(args...) #args
436 #elif __i386__
437 # define CLEAN_FOR_64_BIT(args...) #args
438 #else
439 # define CLEAN_FOR_64_BIT(args...) "CLEAN_FOR_64_BIT_undefined"
440 #endif
441
442 #if defined(__arm__) || defined(__aarch64__)
443 /*
444 * NOTE: The following are not defined for __ARM_EABI__. Each redirects
445 * to a different kernel call. See __NR_getrlimit__ for an example.
446 * __NR_time, __NR_umount, __NR_stime, __NR_alarm, __NR_utime, __NR_getrlimit,
447 * __NR_select, __NR_readdir, __NR_mmap, __NR_socketcall, __NR_syscall,
448 * __NR_ipc, __NR_get_thread_area, __NR_set_thread_area
449 */
450 #endif
451
452 // gcc-3.4 issues a warning that noreturn function returns, if declared noreturn
453 static inline void mtcp_abort (void) __attribute__ ((noreturn));
454 static inline void mtcp_abort (void)
455 {
456 #if defined(__i386__) || defined(__x86_64__)
457 asm volatile (CLEAN_FOR_64_BIT(hlt ; xor %eax,%eax ; mov (%eax),%eax) );
458 #elif defined(__arm__)
459 asm volatile ("mov r0, #0 ; str r0, [r0]");
460 #elif defined(__aarch64__)
461 asm volatile ("mov x0, #0 ; str x0, [X0]");
462 #endif
463 for (;;); /* Without this, gcc emits warning: `noreturn' fnc does return */
464 }
465
466 #endif
467
468 // For DMTCP-2.2, we are definining MTCP_SYS_ERRNO_ON_STACK on command line.
469 // After that, we will move this code to libmtcp.so, where we can again
470 // use global variables, and so will not need this defined.
471 #if defined(__arm__) || defined(__aarch64__)
472 # undef mtcp_inline_syscall
473 # undef INLINE_SYSCALL_RAW
474 # if defined(__arm__)
475 extern unsigned int mtcp_syscall();
476 # elif defined(__aarch64__)
477 extern unsigned long mtcp_syscall();
478 # endif
479 # ifdef MTCP_SYS_ERRNO_ON_STACK
480 # define mtcp_inline_syscall(name, num_args, ...) \
481 mtcp_syscall(SYS_##name, &mtcp_sys_errno, ##__VA_ARGS__)
482 # define INLINE_SYSCALL_RAW(name, nr, ...) \
483 mtcp_syscall(name, &mtcp_sys_errno, ##__VA_ARGS__)
484 # else
485 # define mtcp_inline_syscall(name, num_args, args...) \
486 mtcp_syscall(SYS_##name, args)
487 # define INLINE_SYSCALL_RAW(name, nr, ...) \
488 mtcp_syscall(name, ##__VA_ARGS__)
489 # endif
490 #endif