root/mtcp/mtcp_sys.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. 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

/* [<][>][^][v][top][bottom][index][help] */