LCOV - code coverage report
Current view: directory - src/trusted/service_runtime - nacl_syscall_common.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 450 191 42.4 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * NaCl service run-time, non-platform specific system call helper routines.
       9                 :  */
      10                 : #include <sys/types.h>
      11                 : #include <sys/stat.h>
      12                 : 
      13                 : #include <errno.h>
      14                 : #include <stdio.h>
      15                 : #if NACL_WINDOWS
      16                 : #include <windows.h>
      17                 : #endif
      18                 : 
      19                 : #include "native_client/src/trusted/service_runtime/nacl_syscall_common.h"
      20                 : 
      21                 : #include "native_client/src/include/nacl_macros.h"
      22                 : #include "native_client/src/include/portability_process.h"
      23                 : #include "native_client/src/include/portability_string.h"
      24                 : 
      25                 : #include "native_client/src/shared/platform/nacl_check.h"
      26                 : #include "native_client/src/shared/platform/nacl_clock.h"
      27                 : #include "native_client/src/shared/platform/nacl_exit.h"
      28                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      29                 : #include "native_client/src/shared/platform/nacl_time.h"
      30                 : 
      31                 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
      32                 : #include "native_client/src/trusted/desc/nacl_desc_cond.h"
      33                 : #include "native_client/src/trusted/desc/nacl_desc_mutex.h"
      34                 : #include "native_client/src/trusted/desc/nacl_desc_semaphore.h"
      35                 : 
      36                 : #include "native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h"
      37                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
      38                 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
      39                 : #include "native_client/src/trusted/service_runtime/include/sys/unistd.h"
      40                 : 
      41                 : #include "native_client/src/trusted/service_runtime/include/sys/nacl_test_crash.h"
      42                 : 
      43                 : #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
      44                 : #include "native_client/src/trusted/service_runtime/nacl_copy.h"
      45                 : #include "native_client/src/trusted/service_runtime/nacl_globals.h"
      46                 : #include "native_client/src/trusted/service_runtime/nacl_syscall_handlers.h"
      47                 : #include "native_client/src/trusted/service_runtime/nacl_thread_nice.h"
      48                 : #include "native_client/src/trusted/service_runtime/nacl_tls.h"
      49                 : #include "native_client/src/trusted/service_runtime/sel_ldr.h"
      50                 : 
      51                 : 
      52                 : /*
      53                 :  * OSX defines SIZE_T_MAX in i386/limits.h; Linux has SIZE_MAX;
      54                 :  * Windows has none.
      55                 :  *
      56                 :  * TODO(bsy): remove when we put SIZE_T_MAX in a common header file.
      57                 :  */
      58                 : #if !defined(SIZE_T_MAX)
      59                 : # define SIZE_T_MAX   (~(size_t) 0)
      60                 : #endif
      61                 : 
      62                 : struct NaClSyscallTableEntry nacl_syscall[NACL_MAX_SYSCALLS] = {{0}};
      63                 : 
      64                 : 
      65               0 : int32_t NaClSysNotImplementedDecoder(struct NaClAppThread *natp) {
      66               0 :   NaClCopyDropLock(natp->nap);
      67               0 :   return -NACL_ABI_ENOSYS;
      68                 : }
      69                 : 
      70           22003 : void NaClAddSyscall(int num, int32_t (*fn)(struct NaClAppThread *)) {
      71           22003 :   if (nacl_syscall[num].handler != &NaClSysNotImplementedDecoder) {
      72               0 :     NaClLog(LOG_FATAL, "Duplicate syscall number %d\n", num);
      73               0 :   }
      74           22003 :   nacl_syscall[num].handler = fn;
      75           22003 : }
      76                 : 
      77         1412585 : int32_t NaClSysNull(struct NaClAppThread *natp) {
      78         2825170 :   UNREFERENCED_PARAMETER(natp);
      79         1412585 :   return 0;
      80                 : }
      81                 : 
      82                 : int NaClAclBypassChecks = 0;
      83                 : 
      84                 : void NaClInsecurelyBypassAllAclChecks(void) {
      85             261 :   NaClLog(LOG_WARNING, "BYPASSING ALL ACL CHECKS\n");
      86             261 :   NaClAclBypassChecks = 1;
      87             261 : }
      88                 : 
      89                 : int NaClHighResolutionTimerEnabled(void) {
      90              13 :   return NaClAclBypassChecks;
      91                 : }
      92                 : 
      93               6 : int32_t NaClSysGetpid(struct NaClAppThread *natp) {
      94               6 :   int32_t pid;
      95              12 :   UNREFERENCED_PARAMETER(natp);
      96                 : 
      97               6 :   if (NaClAclBypassChecks) {
      98               6 :     pid = GETPID();
      99               6 :   } else {
     100               0 :     pid = -NACL_ABI_ENOSYS;
     101                 :   }
     102               6 :   NaClLog(4, "NaClSysGetpid: returning %d\n", pid);
     103                 : 
     104               6 :   return pid;
     105                 : }
     106                 : 
     107             243 : int32_t NaClSysExit(struct NaClAppThread  *natp,
     108             243 :                     int                   status) {
     109             243 :   struct NaClApp *nap = natp->nap;
     110                 : 
     111             243 :   NaClLog(1, "Exit syscall handler: %d\n", status);
     112                 : 
     113             243 :   (void) NaClReportExitStatus(nap, NACL_ABI_W_EXITCODE(status, 0));
     114                 : 
     115             243 :   NaClAppThreadTeardown(natp);
     116                 :   /* NOTREACHED */
     117             243 :   return -NACL_ABI_EINVAL;
     118                 : }
     119                 : 
     120           19704 : int32_t NaClSysThreadExit(struct NaClAppThread  *natp,
     121           19704 :                           int32_t               *stack_flag) {
     122           19704 :   uint32_t  zero = 0;
     123                 : 
     124           19704 :   NaClLog(4, "NaClSysThreadExit(0x%08"NACL_PRIxPTR", "
     125                 :           "0x%08"NACL_PRIxPTR"\n",
     126                 :           (uintptr_t) natp,
     127                 :           (uintptr_t) stack_flag);
     128                 :   /*
     129                 :    * NB: NaClThreads are never joinable, but the abstraction for NaClApps
     130                 :    * are.
     131                 :    */
     132                 : 
     133           19704 :   if (NULL != stack_flag) {
     134           19703 :     NaClLog(4,
     135                 :             "NaClSysThreadExit: stack_flag is %"NACL_PRIxPTR"\n",
     136                 :             (uintptr_t) stack_flag);
     137           19703 :     if (!NaClCopyOutToUser(natp->nap, (uintptr_t) stack_flag,
     138                 :                            &zero, sizeof zero)) {
     139               0 :       NaClLog(4,
     140                 :               ("NaClSysThreadExit: ignoring invalid"
     141                 :                " stack_flag 0x%"NACL_PRIxPTR"\n"),
     142                 :               (uintptr_t) stack_flag);
     143               0 :     }
     144           19703 :   }
     145                 : 
     146           19704 :   NaClAppThreadTeardown(natp);
     147                 :   /* NOTREACHED */
     148           19704 :   return -NACL_ABI_EINVAL;
     149                 : }
     150                 : 
     151               4 : int32_t NaClSysNameService(struct NaClAppThread *natp,
     152               4 :                            int32_t              *desc_addr) {
     153               4 :   struct NaClApp *nap = natp->nap;
     154               4 :   int32_t   retval = -NACL_ABI_EINVAL;
     155               4 :   int32_t   desc;
     156                 : 
     157               4 :   NaClLog(3,
     158                 :           ("NaClSysNameService(0x%08"NACL_PRIxPTR","
     159                 :            " 0x%08"NACL_PRIxPTR")\n"),
     160                 :           (uintptr_t) natp,
     161                 :           (uintptr_t) desc_addr);
     162                 : 
     163               4 :   if (!NaClCopyInFromUser(nap, &desc, (uintptr_t) desc_addr, sizeof desc)) {
     164               0 :     NaClLog(LOG_ERROR,
     165                 :             "Invalid address argument to NaClSysNameService\n");
     166               0 :     retval = -NACL_ABI_EFAULT;
     167               0 :     goto done;
     168                 :   }
     169                 : 
     170               4 :   if (-1 == desc) {
     171                 :     /* read */
     172               4 :     desc = NaClAppSetDescAvail(nap, NaClDescRef(nap->name_service_conn_cap));
     173               4 :     if (NaClCopyOutToUser(nap, (uintptr_t) desc_addr,
     174                 :                           &desc, sizeof desc)) {
     175               4 :       retval = 0;
     176               4 :     } else {
     177               0 :       retval = -NACL_ABI_EFAULT;
     178                 :     }
     179               4 :   } else {
     180               0 :     struct NaClDesc *desc_obj_ptr = NaClAppGetDesc(nap, desc);
     181                 : 
     182               0 :     if (NULL == desc_obj_ptr) {
     183               0 :       retval = -NACL_ABI_EBADF;
     184               0 :       goto done;
     185                 :     }
     186               0 :     if (NACL_DESC_CONN_CAP != NACL_VTBL(NaClDesc, desc_obj_ptr)->typeTag &&
     187                 :         NACL_DESC_CONN_CAP_FD != NACL_VTBL(NaClDesc, desc_obj_ptr)->typeTag) {
     188               0 :       retval = -NACL_ABI_EINVAL;
     189               0 :       goto done;
     190                 :     }
     191                 :     /* write */
     192               0 :     NaClXMutexLock(&nap->mu);
     193               0 :     NaClDescUnref(nap->name_service_conn_cap);
     194               0 :     nap->name_service_conn_cap = desc_obj_ptr;
     195               0 :     NaClXMutexUnlock(&nap->mu);
     196               0 :     retval = 0;
     197               4 :   }
     198                 : 
     199                 :  done:
     200               4 :   return retval;
     201                 : }
     202                 : 
     203             242 : int32_t NaClSysTlsInit(struct NaClAppThread  *natp,
     204             242 :                        uint32_t              thread_ptr) {
     205             242 :   int32_t   retval = -NACL_ABI_EINVAL;
     206             242 :   uintptr_t sys_tls;
     207                 : 
     208             242 :   NaClLog(3,
     209                 :           ("Entered NaClSysTlsInit(0x%08"NACL_PRIxPTR
     210                 :            ", 0x%08"NACL_PRIxPTR")\n"),
     211                 :           (uintptr_t) natp, (uintptr_t) thread_ptr);
     212                 : 
     213                 :   /* Verify that the address in the app's range and translated from
     214                 :    * nacl module address to service runtime address - a nop on ARM
     215                 :    */
     216             242 :   sys_tls = NaClUserToSysAddrRange(natp->nap, thread_ptr, 4);
     217             242 :   NaClLog(4,
     218                 :           "NaClSysTlsInit: thread_ptr 0x%"NACL_PRIx32
     219                 :           ", sys_tls 0x%"NACL_PRIxPTR"\n",
     220                 :           thread_ptr, sys_tls);
     221             242 :   if (kNaClBadAddress == sys_tls) {
     222               0 :     retval = -NACL_ABI_EFAULT;
     223               0 :     goto cleanup;
     224                 :   }
     225                 : 
     226             242 :   NaClTlsSetTlsValue1(natp, thread_ptr);
     227             242 :   retval = 0;
     228                 : cleanup:
     229             242 :   return retval;
     230                 : }
     231                 : 
     232           20613 : int32_t NaClSysThreadCreate(struct NaClAppThread *natp,
     233           20613 :                             void                 *prog_ctr,
     234           20613 :                             uint32_t             stack_ptr,
     235           20613 :                             uint32_t             thread_ptr,
     236           20613 :                             uint32_t             second_thread_ptr) {
     237           20613 :   struct NaClApp *nap = natp->nap;
     238           20613 :   int32_t     retval = -NACL_ABI_EINVAL;
     239           20613 :   uintptr_t   sys_tls;
     240           20613 :   uintptr_t   sys_stack;
     241                 : 
     242           20613 :   NaClLog(3,
     243                 :           ("Entered NaClSysThreadCreate(0x%08"NACL_PRIxPTR
     244                 :            " pc=0x%08"NACL_PRIxPTR", sp=0x%08"NACL_PRIx32", thread_ptr=0x%08"
     245                 :            NACL_PRIx32")\n"),
     246                 :           (uintptr_t) natp, (uintptr_t) prog_ctr, stack_ptr, thread_ptr);
     247                 : 
     248           20613 :   if (!NaClIsValidJumpTarget(nap, (uintptr_t) prog_ctr)) {
     249               2 :     NaClLog(LOG_ERROR, "NaClSysThreadCreate: Bad function pointer\n");
     250               2 :     retval = -NACL_ABI_EFAULT;
     251               2 :     goto cleanup;
     252                 :   }
     253                 : 
     254                 :   /* Align the stack pointer. */
     255           20611 :   stack_ptr = ((stack_ptr + NACL_STACK_PAD_BELOW_ALIGN)
     256                 :                & ~NACL_STACK_ALIGN_MASK) - NACL_STACK_PAD_BELOW_ALIGN
     257                 :               - NACL_STACK_ARGS_SIZE;
     258                 : 
     259           20611 :   sys_stack = NaClUserToSysAddr(nap, stack_ptr);
     260           20611 :   if (kNaClBadAddress == sys_stack) {
     261               0 :     NaClLog(LOG_ERROR, "bad stack\n");
     262               0 :     retval = -NACL_ABI_EFAULT;
     263               0 :     goto cleanup;
     264                 :   }
     265           20611 :   sys_tls = NaClUserToSysAddrRange(nap, thread_ptr, 4);
     266           20611 :   if (kNaClBadAddress == sys_tls) {
     267               0 :     NaClLog(LOG_ERROR, "bad TLS pointer\n");
     268               0 :     retval = -NACL_ABI_EFAULT;
     269               0 :     goto cleanup;
     270                 :   }
     271                 : 
     272           20611 :   NaClVmHoleWaitToStartThread(nap);
     273                 : 
     274           20611 :   retval = NaClCreateAdditionalThread(nap,
     275                 :                                       (uintptr_t) prog_ctr,
     276                 :                                       sys_stack,
     277                 :                                       thread_ptr,
     278                 :                                       second_thread_ptr);
     279                 : 
     280                 : cleanup:
     281           20613 :   return retval;
     282                 : }
     283                 : 
     284                 : /*
     285                 :  * This is not used on x86-64 and its functionality is replaced by
     286                 :  * NaClGetTlsFastPath1 (see nacl_syscall_64.S).
     287                 :  */
     288               0 : int32_t NaClSysTlsGet(struct NaClAppThread *natp) {
     289               0 :   return NaClTlsGetTlsValue1(natp);
     290                 : }
     291                 : 
     292               9 : int32_t NaClSysSecondTlsSet(struct NaClAppThread *natp,
     293               9 :                             uint32_t             new_value) {
     294               9 :   NaClTlsSetTlsValue2(natp, new_value);
     295               9 :   return 0;
     296                 : }
     297                 : 
     298                 : /*
     299                 :  * This is not used on x86-64 and its functionality is replaced by
     300                 :  * NaClGetTlsFastPath2 (see nacl_syscall_64.S).
     301                 :  */
     302               0 : int32_t NaClSysSecondTlsGet(struct NaClAppThread *natp) {
     303               0 :   return NaClTlsGetTlsValue2(natp);
     304                 : }
     305                 : 
     306               0 : int NaClSysThreadNice(struct NaClAppThread *natp,
     307               0 :                       const int            nice) {
     308                 :   /* Note: implementation of nacl_thread_nice is OS dependent. */
     309               0 :   UNREFERENCED_PARAMETER(natp);
     310               0 :   return nacl_thread_nice(nice);
     311                 : }
     312                 : 
     313               0 : int32_t NaClSysMutexCreate(struct NaClAppThread *natp) {
     314               0 :   struct NaClApp       *nap = natp->nap;
     315               0 :   int32_t              retval = -NACL_ABI_EINVAL;
     316               0 :   struct NaClDescMutex *desc;
     317                 : 
     318               0 :   NaClLog(3,
     319                 :           ("Entered NaClSysMutexCreate(0x%08"NACL_PRIxPTR")\n"),
     320                 :           (uintptr_t) natp);
     321                 : 
     322               0 :   desc = malloc(sizeof(*desc));
     323                 : 
     324               0 :   if (!desc || !NaClDescMutexCtor(desc)) {
     325               0 :     retval = -NACL_ABI_ENOMEM;
     326               0 :     goto cleanup;
     327                 :   }
     328                 : 
     329               0 :   retval = NaClAppSetDescAvail(nap, (struct NaClDesc *) desc);
     330               0 :   desc = NULL;
     331                 : cleanup:
     332               0 :   free(desc);
     333               0 :   NaClLog(3,
     334                 :           ("NaClSysMutexCreate(0x%08"NACL_PRIxPTR") = %d\n"),
     335                 :           (uintptr_t) natp, retval);
     336               0 :   return retval;
     337                 : }
     338                 : 
     339               0 : int32_t NaClSysMutexLock(struct NaClAppThread  *natp,
     340               0 :                          int32_t               mutex_handle) {
     341               0 :   struct NaClApp        *nap = natp->nap;
     342               0 :   int32_t               retval = -NACL_ABI_EINVAL;
     343               0 :   struct NaClDesc       *desc;
     344                 : 
     345               0 :   NaClLog(3,
     346                 :           ("Entered NaClSysMutexLock(0x%08"NACL_PRIxPTR", %d)\n"),
     347                 :           (uintptr_t) natp, mutex_handle);
     348                 : 
     349               0 :   desc = NaClAppGetDesc(nap, mutex_handle);
     350                 : 
     351               0 :   if (NULL == desc) {
     352               0 :     retval = -NACL_ABI_EBADF;
     353               0 :     goto cleanup;
     354                 :   }
     355                 : 
     356               0 :   retval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->Lock)(desc);
     357               0 :   NaClDescUnref(desc);
     358                 : 
     359                 : cleanup:
     360               0 :   return retval;
     361                 : }
     362                 : 
     363               0 : int32_t NaClSysMutexUnlock(struct NaClAppThread  *natp,
     364               0 :                            int32_t               mutex_handle) {
     365               0 :   struct NaClApp  *nap = natp->nap;
     366               0 :   int32_t         retval = -NACL_ABI_EINVAL;
     367               0 :   struct NaClDesc *desc;
     368                 : 
     369               0 :   NaClLog(3,
     370                 :           ("Entered NaClSysMutexUnlock(0x%08"NACL_PRIxPTR", %d)\n"),
     371                 :           (uintptr_t) natp, mutex_handle);
     372                 : 
     373               0 :   desc = NaClAppGetDesc(nap, mutex_handle);
     374                 : 
     375               0 :   if (NULL == desc) {
     376               0 :     retval = -NACL_ABI_EBADF;
     377               0 :     goto cleanup;
     378                 :   }
     379                 : 
     380               0 :   retval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->Unlock)(desc);
     381               0 :   NaClDescUnref(desc);
     382                 : 
     383                 : cleanup:
     384               0 :   return retval;
     385                 : }
     386                 : 
     387               0 : int32_t NaClSysMutexTrylock(struct NaClAppThread   *natp,
     388               0 :                             int32_t                 mutex_handle) {
     389               0 :   struct NaClApp  *nap = natp->nap;
     390               0 :   int32_t         retval = -NACL_ABI_EINVAL;
     391               0 :   struct NaClDesc *desc;
     392                 : 
     393               0 :   NaClLog(3,
     394                 :           ("Entered NaClSysMutexTrylock(0x%08"NACL_PRIxPTR", %d)\n"),
     395                 :           (uintptr_t) natp, mutex_handle);
     396                 : 
     397               0 :   desc = NaClAppGetDesc(nap, mutex_handle);
     398                 : 
     399               0 :   if (NULL == desc) {
     400               0 :     retval = -NACL_ABI_EBADF;
     401               0 :     goto cleanup;
     402                 :   }
     403                 : 
     404               0 :   retval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->TryLock)(desc);
     405               0 :   NaClDescUnref(desc);
     406                 : 
     407                 : cleanup:
     408               0 :   return retval;
     409                 : }
     410                 : 
     411               0 : int32_t NaClSysCondCreate(struct NaClAppThread *natp) {
     412               0 :   struct NaClApp         *nap = natp->nap;
     413               0 :   int32_t                retval = -NACL_ABI_EINVAL;
     414               0 :   struct NaClDescCondVar *desc;
     415                 : 
     416               0 :   NaClLog(3,
     417                 :           ("Entered NaClSysCondCreate(0x%08"NACL_PRIxPTR")\n"),
     418                 :           (uintptr_t) natp);
     419                 : 
     420               0 :   desc = malloc(sizeof(*desc));
     421                 : 
     422               0 :   if (!desc || !NaClDescCondVarCtor(desc)) {
     423               0 :     retval = -NACL_ABI_ENOMEM;
     424               0 :     goto cleanup;
     425                 :   }
     426                 : 
     427               0 :   retval = NaClAppSetDescAvail(nap, (struct NaClDesc *)desc);
     428               0 :   desc = NULL;
     429                 : cleanup:
     430               0 :   free(desc);
     431               0 :   NaClLog(3,
     432                 :           ("NaClSysCondCreate(0x%08"NACL_PRIxPTR") = %d\n"),
     433                 :           (uintptr_t) natp, retval);
     434               0 :   return retval;
     435                 : }
     436                 : 
     437               0 : int32_t NaClSysCondWait(struct NaClAppThread *natp,
     438               0 :                         int32_t              cond_handle,
     439               0 :                         int32_t              mutex_handle) {
     440               0 :   struct NaClApp  *nap = natp->nap;
     441               0 :   int32_t         retval = -NACL_ABI_EINVAL;
     442               0 :   struct NaClDesc *cv_desc;
     443               0 :   struct NaClDesc *mutex_desc;
     444                 : 
     445               0 :   NaClLog(3,
     446                 :           ("Entered NaClSysCondWait(0x%08"NACL_PRIxPTR", %d, %d)\n"),
     447                 :           (uintptr_t) natp, cond_handle, mutex_handle);
     448                 : 
     449               0 :   cv_desc = NaClAppGetDesc(nap, cond_handle);
     450                 : 
     451               0 :   if (NULL == cv_desc) {
     452               0 :     retval = -NACL_ABI_EBADF;
     453               0 :     goto cleanup;
     454                 :   }
     455                 : 
     456               0 :   mutex_desc = NaClAppGetDesc(nap, mutex_handle);
     457               0 :   if (NULL == mutex_desc) {
     458               0 :     NaClDescUnref(cv_desc);
     459               0 :     retval = -NACL_ABI_EBADF;
     460               0 :     goto cleanup;
     461                 :   }
     462                 : 
     463               0 :   retval = (*((struct NaClDescVtbl const *) cv_desc->base.vtbl)->
     464                 :             Wait)(cv_desc, mutex_desc);
     465               0 :   NaClDescUnref(cv_desc);
     466               0 :   NaClDescUnref(mutex_desc);
     467                 : 
     468                 : cleanup:
     469               0 :   return retval;
     470                 : }
     471                 : 
     472               0 : int32_t NaClSysCondSignal(struct NaClAppThread *natp,
     473               0 :                           int32_t              cond_handle) {
     474               0 :   struct NaClApp  *nap = natp->nap;
     475               0 :   int32_t         retval = -NACL_ABI_EINVAL;
     476               0 :   struct NaClDesc *desc;
     477                 : 
     478               0 :   NaClLog(3,
     479                 :           ("Entered NaClSysCondSignal(0x%08"NACL_PRIxPTR", %d)\n"),
     480                 :           (uintptr_t) natp, cond_handle);
     481                 : 
     482               0 :   desc = NaClAppGetDesc(nap, cond_handle);
     483                 : 
     484               0 :   if (NULL == desc) {
     485               0 :     retval = -NACL_ABI_EBADF;
     486               0 :     goto cleanup;
     487                 :   }
     488                 : 
     489               0 :   retval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->Signal)(desc);
     490               0 :   NaClDescUnref(desc);
     491                 : cleanup:
     492               0 :   return retval;
     493                 : }
     494                 : 
     495               0 : int32_t NaClSysCondBroadcast(struct NaClAppThread  *natp,
     496               0 :                              int32_t               cond_handle) {
     497               0 :   struct NaClApp  *nap = natp->nap;
     498               0 :   struct NaClDesc *desc;
     499               0 :   int32_t         retval = -NACL_ABI_EINVAL;
     500                 : 
     501               0 :   NaClLog(3,
     502                 :           ("Entered NaClSysCondBroadcast(0x%08"NACL_PRIxPTR", %d)\n"),
     503                 :           (uintptr_t) natp, cond_handle);
     504                 : 
     505               0 :   desc = NaClAppGetDesc(nap, cond_handle);
     506                 : 
     507               0 :   if (NULL == desc) {
     508               0 :     retval = -NACL_ABI_EBADF;
     509               0 :     goto cleanup;
     510                 :   }
     511                 : 
     512               0 :   retval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->Broadcast)(desc);
     513               0 :   NaClDescUnref(desc);
     514                 : 
     515                 : cleanup:
     516               0 :   return retval;
     517                 : }
     518                 : 
     519               0 : int32_t NaClSysCondTimedWaitAbs(struct NaClAppThread     *natp,
     520               0 :                                 int32_t                  cond_handle,
     521               0 :                                 int32_t                  mutex_handle,
     522               0 :                                 struct nacl_abi_timespec *ts) {
     523               0 :   struct NaClApp           *nap = natp->nap;
     524               0 :   int32_t                  retval = -NACL_ABI_EINVAL;
     525               0 :   struct NaClDesc          *cv_desc;
     526               0 :   struct NaClDesc          *mutex_desc;
     527               0 :   struct nacl_abi_timespec trusted_ts;
     528                 : 
     529               0 :   NaClLog(3,
     530                 :           ("Entered NaClSysCondTimedWaitAbs(0x%08"NACL_PRIxPTR
     531                 :            ", %d, %d, 0x%08"NACL_PRIxPTR")\n"),
     532                 :           (uintptr_t) natp, cond_handle, mutex_handle, (uintptr_t) ts);
     533                 : 
     534               0 :   if (!NaClCopyInFromUser(nap, &trusted_ts,
     535                 :                           (uintptr_t) ts, sizeof trusted_ts)) {
     536               0 :     retval = -NACL_ABI_EFAULT;
     537               0 :     goto cleanup;
     538                 :   }
     539                 :   /* TODO(gregoryd): validate ts - do we have a limit for time to wait? */
     540                 : 
     541               0 :   cv_desc = NaClAppGetDesc(nap, cond_handle);
     542               0 :   if (NULL == cv_desc) {
     543               0 :     retval = -NACL_ABI_EBADF;
     544               0 :     goto cleanup;
     545                 :   }
     546                 : 
     547               0 :   mutex_desc = NaClAppGetDesc(nap, mutex_handle);
     548               0 :   if (NULL == mutex_desc) {
     549               0 :     NaClDescUnref(cv_desc);
     550               0 :     retval = -NACL_ABI_EBADF;
     551               0 :     goto cleanup;
     552                 :   }
     553                 : 
     554               0 :   retval = (*((struct NaClDescVtbl const *) cv_desc->base.vtbl)->
     555                 :             TimedWaitAbs)(cv_desc,
     556                 :                           mutex_desc,
     557                 :                           &trusted_ts);
     558               0 :   NaClDescUnref(cv_desc);
     559               0 :   NaClDescUnref(mutex_desc);
     560                 : cleanup:
     561               0 :   return retval;
     562                 : }
     563                 : 
     564               0 : int32_t NaClSysSemCreate(struct NaClAppThread *natp,
     565               0 :                          int32_t              init_value) {
     566               0 :   struct NaClApp           *nap = natp->nap;
     567               0 :   int32_t                  retval = -NACL_ABI_EINVAL;
     568               0 :   struct NaClDescSemaphore *desc;
     569                 : 
     570               0 :   NaClLog(3,
     571                 :           ("Entered NaClSysSemCreate(0x%08"NACL_PRIxPTR
     572                 :            ", %d)\n"),
     573                 :           (uintptr_t) natp, init_value);
     574                 : 
     575               0 :   desc = malloc(sizeof(*desc));
     576                 : 
     577               0 :   if (!desc || !NaClDescSemaphoreCtor(desc, init_value)) {
     578               0 :     retval = -NACL_ABI_ENOMEM;
     579               0 :     goto cleanup;
     580                 :   }
     581                 : 
     582               0 :   retval = NaClAppSetDescAvail(nap, (struct NaClDesc *) desc);
     583               0 :   desc = NULL;
     584                 : cleanup:
     585               0 :   free(desc);
     586               0 :   return retval;
     587                 : }
     588                 : 
     589                 : 
     590               0 : int32_t NaClSysSemWait(struct NaClAppThread *natp,
     591               0 :                        int32_t              sem_handle) {
     592               0 :   struct NaClApp  *nap = natp->nap;
     593               0 :   int32_t         retval = -NACL_ABI_EINVAL;
     594               0 :   struct NaClDesc *desc;
     595                 : 
     596               0 :   NaClLog(3,
     597                 :           ("Entered NaClSysSemWait(0x%08"NACL_PRIxPTR
     598                 :            ", %d)\n"),
     599                 :           (uintptr_t) natp, sem_handle);
     600                 : 
     601               0 :   desc = NaClAppGetDesc(nap, sem_handle);
     602                 : 
     603               0 :   if (NULL == desc) {
     604               0 :     retval = -NACL_ABI_EBADF;
     605               0 :     goto cleanup;
     606                 :   }
     607                 : 
     608                 :   /*
     609                 :    * TODO(gregoryd): we have to decide on the syscall API: do we
     610                 :    * switch to read/write/ioctl API or do we stay with the more
     611                 :    * detailed API. Anyway, using a single syscall for waiting on all
     612                 :    * synchronization objects makes sense.
     613                 :    */
     614               0 :   retval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->SemWait)(desc);
     615               0 :   NaClDescUnref(desc);
     616                 : cleanup:
     617               0 :   return retval;
     618                 : }
     619                 : 
     620               0 : int32_t NaClSysSemPost(struct NaClAppThread *natp,
     621               0 :                        int32_t              sem_handle) {
     622               0 :   struct NaClApp  *nap = natp->nap;
     623               0 :   int32_t         retval = -NACL_ABI_EINVAL;
     624               0 :   struct NaClDesc *desc;
     625                 : 
     626               0 :   NaClLog(3,
     627                 :           ("Entered NaClSysSemPost(0x%08"NACL_PRIxPTR
     628                 :            ", %d)\n"),
     629                 :           (uintptr_t) natp, sem_handle);
     630                 : 
     631               0 :   desc = NaClAppGetDesc(nap, sem_handle);
     632                 : 
     633               0 :   if (NULL == desc) {
     634               0 :     retval = -NACL_ABI_EBADF;
     635               0 :     goto cleanup;
     636                 :   }
     637                 : 
     638               0 :   retval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->Post)(desc);
     639               0 :   NaClDescUnref(desc);
     640                 : cleanup:
     641               0 :   return retval;
     642                 : }
     643                 : 
     644               0 : int32_t NaClSysSemGetValue(struct NaClAppThread *natp,
     645               0 :                            int32_t              sem_handle) {
     646               0 :   struct NaClApp  *nap = natp->nap;
     647               0 :   int32_t         retval = -NACL_ABI_EINVAL;
     648               0 :   struct NaClDesc *desc;
     649                 : 
     650               0 :   NaClLog(3,
     651                 :           ("Entered NaClSysSemGetValue(0x%08"NACL_PRIxPTR
     652                 :            ", %d)\n"),
     653                 :           (uintptr_t) natp, sem_handle);
     654                 : 
     655               0 :   desc = NaClAppGetDesc(nap, sem_handle);
     656                 : 
     657               0 :   if (NULL == desc) {
     658               0 :     retval = -NACL_ABI_EBADF;
     659               0 :     goto cleanup;
     660                 :   }
     661                 : 
     662               0 :   retval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->GetValue)(desc);
     663               0 :   NaClDescUnref(desc);
     664                 : cleanup:
     665               0 :   return retval;
     666                 : }
     667                 : 
     668              73 : int32_t NaClSysNanosleep(struct NaClAppThread     *natp,
     669              73 :                          struct nacl_abi_timespec *req,
     670              73 :                          struct nacl_abi_timespec *rem) {
     671              73 :   struct NaClApp            *nap = natp->nap;
     672              73 :   struct nacl_abi_timespec  t_sleep;
     673              73 :   struct nacl_abi_timespec  t_rem;
     674              73 :   struct nacl_abi_timespec  *remptr;
     675              73 :   int                       retval = -NACL_ABI_EINVAL;
     676                 : 
     677              73 :   NaClLog(3,
     678                 :           ("Entered NaClSysNanosleep(0x%08"NACL_PRIxPTR
     679                 :            ", 0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR"x)\n"),
     680                 :           (uintptr_t) natp, (uintptr_t) req, (uintptr_t) rem);
     681                 : 
     682                 :   /* do the check before we sleep */
     683              73 :   if (NULL != rem && kNaClBadAddress ==
     684              56 :       NaClUserToSysAddrRange(nap, (uintptr_t) rem, sizeof *rem)) {
     685               0 :     retval = -NACL_ABI_EFAULT;
     686               0 :     goto cleanup;
     687                 :   }
     688                 : 
     689              73 :   if (!NaClCopyInFromUser(nap, &t_sleep,
     690                 :                           (uintptr_t) req, sizeof t_sleep)) {
     691               1 :     retval = -NACL_ABI_EFAULT;
     692               1 :     goto cleanup;
     693                 :   }
     694                 : 
     695             213 :   remptr = (NULL == rem) ? NULL : &t_rem;
     696                 :   /* NULL != remptr \equiv NULL != rem */
     697                 : 
     698                 :   /*
     699                 :    * We assume that we do not need to normalize the time request values.
     700                 :    *
     701                 :    * If bogus values can cause the underlying OS to get into trouble,
     702                 :    * then we need more checking here.
     703                 :    */
     704              69 :   NaClLog(4, "NaClSysNanosleep(time = %"NACL_PRId64".%09"NACL_PRId64" S)\n",
     705                 :           (int64_t) t_sleep.tv_sec, (int64_t) t_sleep.tv_nsec);
     706              69 :   retval = NaClNanosleep(&t_sleep, remptr);
     707              69 :   NaClLog(4, "NaClNanosleep returned %d\n", retval);
     708                 : 
     709              69 :   if (-EINTR == retval && NULL != rem &&
     710               0 :       !NaClCopyOutToUser(nap, (uintptr_t) rem, remptr, sizeof *remptr)) {
     711               0 :     NaClLog(LOG_FATAL, "NaClSysNanosleep: check rem failed at copyout\n");
     712              69 :   }
     713                 : 
     714                 : cleanup:
     715              70 :   NaClLog(4, "nanosleep done.\n");
     716              70 :   return retval;
     717                 : }
     718                 : 
     719           17648 : int32_t NaClSysSchedYield(struct NaClAppThread *natp) {
     720           35296 :   UNREFERENCED_PARAMETER(natp);
     721                 : 
     722           17648 :   NaClThreadYield();
     723           17648 :   return 0;
     724                 : }
     725                 : 
     726             231 : int32_t NaClSysSysconf(struct NaClAppThread *natp,
     727             231 :                        int32_t              name,
     728             231 :                        int32_t              *result) {
     729             231 :   struct NaClApp  *nap = natp->nap;
     730             231 :   int32_t         retval = -NACL_ABI_EINVAL;
     731             231 :   int32_t         result_value;
     732                 : 
     733             231 :   NaClLog(3,
     734                 :           ("Entered NaClSysSysconf(%08"NACL_PRIxPTR
     735                 :            "x, %d, 0x%08"NACL_PRIxPTR")\n"),
     736                 :           (uintptr_t) natp, name, (uintptr_t) result);
     737                 : 
     738             231 :   switch (name) {
     739                 :     case NACL_ABI__SC_NPROCESSORS_ONLN: {
     740                 : #if NACL_WINDOWS
     741                 :       static int32_t number_of_workers = 0;
     742                 :       if (0 == number_of_workers) {
     743                 :         SYSTEM_INFO si;
     744                 :         GetSystemInfo(&si);
     745                 :         number_of_workers = (int32_t) si.dwNumberOfProcessors;
     746                 :       }
     747                 :       result_value = number_of_workers;
     748                 : #elif NACL_LINUX || NACL_OSX
     749               2 :       if (-1 == nap->sc_nprocessors_onln) {
     750                 :         /* Unable to get the number of processors at startup. */
     751               0 :         goto cleanup;
     752                 :       }
     753               2 :       result_value = nap->sc_nprocessors_onln;
     754                 : #else
     755                 : #error Unsupported platform
     756                 : #endif
     757               2 :       break;
     758                 :     }
     759                 :     case NACL_ABI__SC_PAGESIZE: {
     760             228 :       result_value = 1 << 16;  /* always 64k pages */
     761             228 :       break;
     762                 :     }
     763                 :     case NACL_ABI__SC_NACL_FILE_ACCESS_ENABLED: {
     764               0 :       result_value = NaClAclBypassChecks;
     765               0 :       break;
     766                 :     }
     767                 :     case NACL_ABI__SC_NACL_LIST_MAPPINGS_ENABLED: {
     768               0 :       result_value = nap->enable_list_mappings;
     769               0 :       break;
     770                 :     }
     771                 :     case NACL_ABI__SC_NACL_PNACL_MODE: {
     772               0 :       result_value = nap->pnacl_mode;
     773               0 :       break;
     774                 :     }
     775                 :     default: {
     776               1 :       retval = -NACL_ABI_EINVAL;
     777               1 :       goto cleanup;
     778                 :     }
     779                 :   }
     780             230 :   if (!NaClCopyOutToUser(nap, (uintptr_t) result, &result_value,
     781                 :                          sizeof result_value)) {
     782               0 :     retval = -NACL_ABI_EFAULT;
     783               0 :     goto cleanup;
     784                 :   }
     785             230 :   retval = 0;
     786                 : cleanup:
     787             231 :   return retval;
     788                 : }
     789                 : 
     790               1 : int32_t NaClSysTestInfoLeak(struct NaClAppThread *natp) {
     791                 : #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
     792                 :   /*
     793                 :    * Put some interesting bits into the x87 and SSE registers.
     794                 :    */
     795                 :   union fxsave {
     796                 :     char buf[512];
     797                 :     struct {
     798                 :       uint16_t fcw;
     799                 :       uint16_t fsw;
     800                 :       uint16_t ftw;
     801                 :       uint16_t fop;
     802                 :       union {
     803                 :         struct {
     804                 :           uint64_t rip;
     805                 :           uint64_t rdp;
     806                 :         } x64;
     807                 :         struct {
     808                 :           uint32_t fpu_ip;
     809                 :           uint32_t cs;
     810                 :           uint32_t fpu_dp;
     811                 :           uint32_t ds;
     812                 :         } ia32;
     813                 :       } bitness;
     814                 :       uint32_t mxcsr;
     815                 :       uint32_t mxcsr_mask;
     816                 :       struct {
     817                 :         uint8_t st[10];
     818                 :         uint8_t reserved[6];
     819                 :       } st_space[8];
     820                 :       uint32_t xmm_space[64];
     821                 :     } fxsave;
     822                 :   };
     823                 : 
     824                 :   static const char tenbytes[10] = "SecretBits";
     825                 :   static const char manybytes[256] =
     826                 :       "Highly sensitive information must not be leaked to untrusted code!\n"
     827                 :       "xyzzy\nplugh\nYou are likely to be eaten by a grue.\n"
     828                 :       "When in the Course of human events it becomes necessary for one people"
     829                 :       " to dissolve the political bands which have connected them with ...\n";
     830                 : 
     831                 : # ifdef __GNUC__
     832               1 :   union fxsave u __attribute__((aligned(16)));
     833                 : # elif NACL_WINDOWS
     834                 :   __declspec(align(16)) union fxsave u;
     835                 : # else
     836                 : #  error Unsupported platform
     837                 : # endif
     838                 : 
     839               1 :   int i;
     840                 : 
     841                 : # ifdef __GNUC__
     842               1 :   __asm__("fxsave %0" : "=m" (u));
     843                 : # elif NACL_WINDOWS
     844                 : #  if NACL_BUILD_SUBARCH == 64
     845                 :   NaClDoFxsave(&u);
     846                 : #  else
     847                 :   __asm {
     848                 :     fxsave u
     849                 :   };
     850                 : #  endif
     851                 : # else
     852                 : # error Unsupported platform
     853                 : # endif
     854                 : 
     855              18 :   for (i = 0; i < 8; ++i)
     856              24 :     memcpy(&u.fxsave.st_space[i], tenbytes, sizeof(tenbytes));
     857                 : 
     858               1 :   memcpy(u.fxsave.xmm_space, manybytes, sizeof(u.fxsave.xmm_space));
     859                 : 
     860                 :   /*
     861                 :    * Set the MXCSR to an unlikely (but valid) value: all valid bits set.
     862                 :    * The mask is provided by the hardware to say which bits can be set
     863                 :    * (all others are reserved).  The untrusted test code (in
     864                 :    * tests/infoleak/test_infoleak.c) sets MXCSR to zero before
     865                 :    * making this system call so this value ensures that the test
     866                 :    * actually verifies the behavior of the syscall return path.
     867                 :    */
     868               1 :   u.fxsave.mxcsr = u.fxsave.mxcsr_mask;
     869                 : 
     870                 : # ifdef __GNUC__
     871               1 :   __asm__ volatile("fxrstor %0" :: "m" (u));
     872                 : # elif NACL_WINDOWS
     873                 : #  if NACL_BUILD_SUBARCH == 64
     874                 :   NaClDoFxrstor(&u);
     875                 : #  else
     876                 :   __asm {
     877                 :     fxrstor u
     878                 :   };
     879                 : #  endif
     880                 : # else
     881                 : # error Unsupported platform
     882                 : # endif
     883                 : 
     884                 : #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
     885                 :   /*
     886                 :    * Put some interesting bits into the VFP registers.
     887                 :    */
     888                 : 
     889                 :   static const char manybytes[64] =
     890                 :       "Sensitive information must not be leaked to untrusted code!!!!\n";
     891                 : 
     892                 :   __asm__ volatile("vldm %0, {d0-d7}" :: "r" (manybytes) :
     893                 :                    "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7");
     894                 :   __asm__ volatile("fmxr fpscr, %0" :: "r" (0xdeadbeef) : "vfpcc");
     895                 : 
     896                 : #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
     897                 : 
     898                 :   static const char manybytes[128] =
     899                 :       "Sensitive information must not be leaked to untrusted code!!!\n"
     900                 :       "Where is Maletoth?\n";
     901                 : 
     902                 :   __asm__ volatile("ldc1  $f0,  0(%0)\n"
     903                 :                    "ldc1  $f2,  8(%0)\n"
     904                 :                    "ldc1  $f4,  16(%0)\n"
     905                 :                    "ldc1  $f6,  24(%0)\n"
     906                 :                    "ldc1  $f8,  32(%0)\n"
     907                 :                    "ldc1  $f10, 40(%0)\n"
     908                 :                    "ldc1  $f12, 48(%0)\n"
     909                 :                    "ldc1  $f14, 56(%0)\n"
     910                 :                    "ldc1  $f16, 64(%0)\n"
     911                 :                    "ldc1  $f18, 72(%0)\n"
     912                 :                    : : "r" (manybytes)
     913                 :                    : "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
     914                 :                      "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14",
     915                 :                      "$f15", "$f16", "$f17", "$f18", "$f19");
     916                 : 
     917                 : #endif
     918                 : 
     919               2 :   UNREFERENCED_PARAMETER(natp);
     920                 : 
     921               1 :   return -NACL_ABI_ENOSYS;
     922                 : }
     923                 : 
     924                 : /*
     925                 :  * This syscall is intended for testing NaCl's support for Breakpad
     926                 :  * crash reporting inside Chromium.  When
     927                 :  * http://code.google.com/p/nativeclient/issues/detail?id=579 is
     928                 :  * addressed, we might put this syscall behind a flag.  Until then,
     929                 :  * untrusted code can trigger Breakpad-reported crashes inside
     930                 :  * syscalls, so there is no benefit to restricting this syscall.
     931                 :  */
     932               2 : int32_t NaClSysTestCrash(struct NaClAppThread *natp, int crash_type) {
     933                 :   /*
     934                 :    * Despite being volatile, the Apple system compiler, llvm-gcc, still
     935                 :    * optimizes the null pointer dereference into an illegal instruction when
     936                 :    * written as a one-liner. That interferes with tests that expect precisely
     937                 :    * a SIGSEGV, because they'll see a SIGILL instead.
     938                 :    */
     939               2 :   volatile int *volatile p = 0;
     940               4 :   UNREFERENCED_PARAMETER(natp);
     941                 : 
     942               2 :   switch (crash_type) {
     943                 :     case NACL_TEST_CRASH_MEMORY:
     944               2 :       *p = 0;
     945               2 :       break;
     946                 :     case NACL_TEST_CRASH_LOG_FATAL:
     947               0 :       NaClLog(LOG_FATAL, "NaClSysTestCrash: This is a test error\n");
     948               0 :       break;
     949                 :     case NACL_TEST_CRASH_CHECK_FAILURE:
     950               0 :       CHECK(0);
     951               0 :       break;
     952                 :   }
     953               0 :   return -NACL_ABI_EINVAL;
     954                 : }
     955                 : 
     956              13 : int32_t NaClSysGetTimeOfDay(struct NaClAppThread      *natp,
     957              13 :                             struct nacl_abi_timeval   *tv,
     958              13 :                             struct nacl_abi_timezone  *tz) {
     959              13 :   int                     retval;
     960              13 :   struct nacl_abi_timeval now;
     961                 : 
     962              26 :   UNREFERENCED_PARAMETER(tz);
     963                 : 
     964              13 :   NaClLog(3,
     965                 :           ("Entered NaClSysGetTimeOfDay(%08"NACL_PRIxPTR
     966                 :            ", 0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR")\n"),
     967                 :           (uintptr_t) natp, (uintptr_t) tv, (uintptr_t) tz);
     968                 : 
     969                 :   /*
     970                 :    * tz is not supported in linux, nor is it supported by glibc, since
     971                 :    * tzset(3) and the zoneinfo file should be used instead.
     972                 :    *
     973                 :    * TODO(bsy) Do we make the zoneinfo directory available to
     974                 :    * applications?
     975                 :    */
     976                 : 
     977              13 :   retval = NaClGetTimeOfDay(&now);
     978              13 :   if (0 != retval) {
     979               0 :     return retval;
     980                 :   }
     981                 : #if !NACL_WINDOWS
     982                 :   /*
     983                 :    * Coarsen the time to the same level we get on Windows -
     984                 :    * 10 microseconds.
     985                 :    */
     986              13 :   if (!NaClHighResolutionTimerEnabled()) {
     987               0 :     now.nacl_abi_tv_usec = (now.nacl_abi_tv_usec / 10) * 10;
     988               0 :   }
     989                 : #endif
     990              39 :   CHECK(now.nacl_abi_tv_usec >= 0);
     991              39 :   CHECK(now.nacl_abi_tv_usec < NACL_MICROS_PER_UNIT);
     992              13 :   if (!NaClCopyOutToUser(natp->nap, (uintptr_t) tv, &now, sizeof now)) {
     993               0 :     return -NACL_ABI_EFAULT;
     994                 :   }
     995              13 :   return 0;
     996              13 : }
     997                 : 
     998          706618 : static int NaClIsValidClockId(int clk_id) {
     999          706618 :   switch (clk_id) {
    1000                 :     case NACL_ABI_CLOCK_REALTIME:
    1001                 :     case NACL_ABI_CLOCK_MONOTONIC:
    1002                 :     case NACL_ABI_CLOCK_PROCESS_CPUTIME_ID:
    1003                 :     case NACL_ABI_CLOCK_THREAD_CPUTIME_ID:
    1004          706618 :       return 1;
    1005                 :   }
    1006               0 :   return 0;
    1007          706618 : }
    1008                 : 
    1009          706618 : static int32_t NaClSysClockGetCommon(struct NaClAppThread  *natp,
    1010          706618 :                                      int                   clk_id,
    1011          706618 :                                      uint32_t              ts_addr,
    1012          706618 :                                      int                   (*timefunc)(
    1013                 :                                          nacl_clockid_t            clk_id,
    1014                 :                                          struct nacl_abi_timespec  *tp),
    1015          706618 :                                      int null_ok) {
    1016          706618 :   struct NaClApp            *nap = natp->nap;
    1017          706618 :   int                       retval = -NACL_ABI_EINVAL;
    1018          706618 :   struct nacl_abi_timespec  out_buf;
    1019                 : 
    1020          706618 :   if (!NaClIsValidClockId(clk_id)) {
    1021               0 :     goto done;
    1022                 :   }
    1023          706618 :   retval = (*timefunc)((nacl_clockid_t) clk_id, &out_buf);
    1024          706618 :   if (0 == retval) {
    1025          706622 :     if (ts_addr == 0 ? !null_ok :
    1026          706614 :         !NaClCopyOutToUser(nap, (uintptr_t) ts_addr,
    1027                 :                            &out_buf, sizeof out_buf)) {
    1028               0 :       retval = -NACL_ABI_EFAULT;
    1029               0 :     }
    1030         1413236 :   }
    1031                 :  done:
    1032          706618 :   return retval;
    1033                 : }
    1034                 : 
    1035               8 : int32_t NaClSysClockGetRes(struct NaClAppThread *natp,
    1036               8 :                            int                  clk_id,
    1037               8 :                            uint32_t             tsp) {
    1038               8 :   return NaClSysClockGetCommon(natp, clk_id, (uintptr_t) tsp,
    1039                 :                                NaClClockGetRes, 1);
    1040                 : }
    1041                 : 
    1042          706610 : int32_t NaClSysClockGetTime(struct NaClAppThread  *natp,
    1043          706610 :                             int                   clk_id,
    1044          706610 :                             uint32_t              tsp) {
    1045          706610 :   return NaClSysClockGetCommon(natp, clk_id, (uintptr_t) tsp,
    1046                 :                                NaClClockGetTime, 0);
    1047                 : }

Generated by: LCOV version 1.7