// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_
#define MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_

#include "native_client/src/trusted/service_runtime/nacl_copy.h"
#include "native_client/src/trusted/service_runtime/sel_ldr.h"

namespace {

class ScopedCopyLock {
 public:
  explicit ScopedCopyLock(struct NaClApp* nap) : nap_(nap) {
    NaClCopyTakeLock(nap_);
  }
  ~ScopedCopyLock() {
    NaClCopyDropLock(nap_);
  }
 private:
  struct NaClApp* nap_;
};

static inline uintptr_t NaClUserToSysAddrArray(
    struct NaClApp* nap,
    uint32_t uaddr,
    size_t count,
    size_t size) {
  // TODO(ncbray): overflow checking
  size_t range = count * size;
  return NaClUserToSysAddrRange(nap, uaddr, range);
}

// We don't use plain-old memcpy because reads and writes to the untrusted
// address space from trusted code must be volatile.  Non-volatile memory
// operations are dangerous because a compiler would be free to materialize a
// second load from the same memory address or materialize a load from a memory
// address that was stored, and assume the materialized load would return the
// same value as the previous load or store.  Data races could cause the
// materialized load to return a different value, however, which could lead to
// time of check vs. time of use problems, or worse.  For this binding code in
// particular, where memcpy is being called with a constant size, it is entirely
// conceivable the function will be inlined, unrolled, and optimized.
static inline void memcpy_volatile_out(
    void volatile* dst,
    const void* src,
    size_t n) {
  char volatile* c_dst = static_cast<char volatile*>(dst);
  const char* c_src = static_cast<const char*>(src);
  for (size_t i = 0; i < n; i++) {
    c_dst[i] = c_src[i];
  }
}

template <typename T> bool ConvertScalarInput(
    struct NaClApp* nap,
    uint32_t user_ptr,
    T* value) {
  if (user_ptr) {
    uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
    if (temp != kNaClBadAddress) {
      *value = *reinterpret_cast<T volatile*>(temp);
      return true;
    }
  }
  return false;
}

template <typename T> bool ConvertScalarOutput(
    struct NaClApp* nap,
    uint32_t user_ptr,
    bool optional,
    T volatile** sys_ptr) {
  if (user_ptr) {
    uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
    if (temp != kNaClBadAddress) {
      *sys_ptr = reinterpret_cast<T volatile*>(temp);
      return true;
    } else if (optional) {
      *sys_ptr = 0;
      return true;
    }
  }
  *sys_ptr = 0; // Paranoia.
  return false;
}

template <typename T> bool ConvertScalarInOut(
    struct NaClApp* nap,
    uint32_t user_ptr,
    bool optional,
    T* value,
    T volatile** sys_ptr) {
  if (user_ptr) {
    uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
    if (temp != kNaClBadAddress) {
      T volatile* converted = reinterpret_cast<T volatile*>(temp);
      *sys_ptr = converted;
      *value = *converted;
      return true;
    }
  } else if (optional) {
    *sys_ptr = 0;
    *value = static_cast<T>(0); // Paranoia.
    return true;
  }
  *sys_ptr = 0; // Paranoia.
  *value = static_cast<T>(0); // Paranoia.
  return false;
}

template <typename T> bool ConvertArray(
    struct NaClApp* nap,
    uint32_t user_ptr,
    uint32_t length,
    size_t element_size,
    bool optional,
    T** sys_ptr) {
  if (user_ptr) {
    uintptr_t temp = NaClUserToSysAddrArray(nap, user_ptr, length,
                                            element_size);
    if (temp != kNaClBadAddress) {
      *sys_ptr = reinterpret_cast<T*>(temp);
      return true;
    }
  } else if (optional) {
    *sys_ptr = 0;
    return true;
  }
  return false;
}

template <typename T> bool ConvertBytes(
    struct NaClApp* nap,
    uint32_t user_ptr,
    uint32_t length,
    bool optional,
    T** sys_ptr) {
  if (user_ptr) {
    uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, length);
    if (temp != kNaClBadAddress) {
      *sys_ptr = reinterpret_cast<T*>(temp);
      return true;
    }
  } else if (optional) {
    *sys_ptr = 0;
    return true;
  }
  return false;
}

// TODO(ncbray): size validation and complete copy.
// TODO(ncbray): ensure non-null / missized structs are covered by a test case.
template <typename T> bool ConvertExtensibleStructInput(
    struct NaClApp* nap,
    uint32_t user_ptr,
    bool optional,
    T** sys_ptr) {
  if (user_ptr) {
    uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
    if (temp != kNaClBadAddress) {
      *sys_ptr = reinterpret_cast<T*>(temp);
      return true;
    }
  } else if (optional) {
    *sys_ptr = 0;
    return true;
  }
  return false;
}

} // namespace

#endif // MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_
