Home | History | Annotate | Download | only in nacl
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_
      6 #define MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_
      7 
      8 #include "native_client/src/trusted/service_runtime/nacl_copy.h"
      9 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
     10 
     11 namespace {
     12 
     13 class ScopedCopyLock {
     14  public:
     15   explicit ScopedCopyLock(struct NaClApp* nap) : nap_(nap) {
     16     NaClCopyTakeLock(nap_);
     17   }
     18   ~ScopedCopyLock() {
     19     NaClCopyDropLock(nap_);
     20   }
     21  private:
     22   struct NaClApp* nap_;
     23 };
     24 
     25 static inline uintptr_t NaClUserToSysAddrArray(
     26     struct NaClApp* nap,
     27     uint32_t uaddr,
     28     size_t count,
     29     size_t size) {
     30   // TODO(ncbray): overflow checking
     31   size_t range = count * size;
     32   return NaClUserToSysAddrRange(nap, uaddr, range);
     33 }
     34 
     35 template <typename T> bool ConvertScalarInput(
     36     struct NaClApp* nap,
     37     uint32_t user_ptr,
     38     T* value) {
     39   if (user_ptr) {
     40     uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
     41     if (temp != kNaClBadAddress) {
     42       *value = *reinterpret_cast<T volatile*>(temp);
     43       return true;
     44     }
     45   }
     46   return false;
     47 }
     48 
     49 template <typename T> bool ConvertScalarOutput(
     50     struct NaClApp* nap,
     51     uint32_t user_ptr,
     52     T volatile** sys_ptr) {
     53   if (user_ptr) {
     54     uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
     55     if (temp != kNaClBadAddress) {
     56       *sys_ptr = reinterpret_cast<T volatile*>(temp);
     57       return true;
     58     }
     59   }
     60   *sys_ptr = 0; // Paranoia.
     61   return false;
     62 }
     63 
     64 template <typename T> bool ConvertScalarInOut(
     65     struct NaClApp* nap,
     66     uint32_t user_ptr,
     67     bool optional,
     68     T* value,
     69     T volatile** sys_ptr) {
     70   if (user_ptr) {
     71     uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
     72     if (temp != kNaClBadAddress) {
     73       T volatile* converted = reinterpret_cast<T volatile*>(temp);
     74       *sys_ptr = converted;
     75       *value = *converted;
     76       return true;
     77     }
     78   } else if (optional) {
     79     *sys_ptr = 0;
     80     *value = static_cast<T>(0); // Paranoia.
     81     return true;
     82   }
     83   *sys_ptr = 0; // Paranoia.
     84   *value = static_cast<T>(0); // Paranoia.
     85   return false;
     86 }
     87 
     88 template <typename T> bool ConvertArray(
     89     struct NaClApp* nap,
     90     uint32_t user_ptr,
     91     uint32_t length,
     92     size_t element_size,
     93     bool optional,
     94     T** sys_ptr) {
     95   if (user_ptr) {
     96     uintptr_t temp = NaClUserToSysAddrArray(nap, user_ptr, length,
     97                                             element_size);
     98     if (temp != kNaClBadAddress) {
     99       *sys_ptr = reinterpret_cast<T*>(temp);
    100       return true;
    101     }
    102   } else if (optional) {
    103     *sys_ptr = 0;
    104     return true;
    105   }
    106   return false;
    107 }
    108 
    109 template <typename T> bool ConvertBytes(
    110     struct NaClApp* nap,
    111     uint32_t user_ptr,
    112     uint32_t length,
    113     bool optional,
    114     T** sys_ptr) {
    115   if (user_ptr) {
    116     uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, length);
    117     if (temp != kNaClBadAddress) {
    118       *sys_ptr = reinterpret_cast<T*>(temp);
    119       return true;
    120     }
    121   } else if (optional) {
    122     *sys_ptr = 0;
    123     return true;
    124   }
    125   return false;
    126 }
    127 
    128 // TODO(ncbray): size validation and complete copy.
    129 // TODO(ncbray): ensure non-null / missized structs are covered by a test case.
    130 template <typename T> bool ConvertStruct(
    131     struct NaClApp* nap,
    132     uint32_t user_ptr,
    133     bool optional,
    134     T** sys_ptr) {
    135   if (user_ptr) {
    136     uintptr_t temp = NaClUserToSysAddrRange(nap, user_ptr, sizeof(T));
    137     if (temp != kNaClBadAddress) {
    138       *sys_ptr = reinterpret_cast<T*>(temp);
    139       return true;
    140     }
    141   } else if (optional) {
    142     *sys_ptr = 0;
    143     return true;
    144   }
    145   return false;
    146 }
    147 
    148 } // namespace
    149 
    150 #endif // MOJO_NACL_MOJO_SYSCALL_INTERNAL_H_
    151