15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <errno.h>
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sched.h>
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <stdlib.h>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sys/time.h>
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <time.h>
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <unistd.h>
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/nacl/loader/nonsfi/abi_conversion.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/nacl/loader/nonsfi/irt_interfaces.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/nacl/loader/nonsfi/irt_util.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "native_client/src/trusted/service_runtime/include/sys/time.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "native_client/src/trusted/service_runtime/include/sys/unistd.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace nacl {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace nonsfi {
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IrtExit(int status) {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  _exit(status);
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int IrtGetToD(struct nacl_abi_timeval* tv) {
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct timeval host_tv;
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (gettimeofday(&host_tv, NULL))
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return errno;
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  tv->nacl_abi_tv_sec = host_tv.tv_sec;
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  tv->nacl_abi_tv_usec = host_tv.tv_usec;
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return 0;
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int IrtClock(nacl_abi_clock_t* ticks) {
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // There is no definition of errno when clock is failed.
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // So we assume it always succeeds.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *ticks = clock();
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return 0;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int IrtNanoSleep(const struct nacl_abi_timespec* req,
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 struct nacl_abi_timespec* rem) {
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct timespec host_req;
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NaClAbiTimeSpecToTimeSpec(*req, &host_req);
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct timespec host_rem;
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (nanosleep(&host_req, &host_rem))
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return errno;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rem)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    TimeSpecToNaClAbiTimeSpec(host_rem, rem);
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return 0;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int IrtSchedYield() {
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return CheckError(sched_yield());
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int IrtSysconf(int name, int* value) {
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int result;
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (name) {
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case NACL_ABI__SC_NPROCESSORS_ONLN:
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      errno = 0;
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = sysconf(_SC_NPROCESSORS_ONLN);
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case NACL_ABI__SC_PAGESIZE:
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      errno = 0;
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = sysconf(_SC_PAGESIZE);
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    default:
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return EINVAL;
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result == -1 && errno == EINVAL)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return EINVAL;
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *value = result;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return 0;
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// For gettod, clock and nanosleep, their argument types should be nacl_abi_X,
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// rather than host type, such as timeval or clock_t etc. However, the
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// definition of nacl_irt_basic uses host types, so here we need to cast them.
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const nacl_irt_basic kIrtBasic = {
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  IrtExit,
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reinterpret_cast<int(*)(struct timeval*)>(IrtGetToD),
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reinterpret_cast<int(*)(clock_t*)>(IrtClock),
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reinterpret_cast<int(*)(const struct timespec*, struct timespec*)>(
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      IrtNanoSleep),
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  IrtSchedYield,
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  IrtSysconf,
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace nonsfi
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace nacl
98